1. 程式人生 > >ObjectiveC(10)_引用計數

ObjectiveC(10)_引用計數

在這裡插入圖片描述 Cocoa中提供了一個機制來實現上圖中的邏輯模型,它被稱為引用計數(reference counting)或保留計數(retain counting)。引用計數的數值表示物件有幾個物件在使用它。實現原理是:

  • 每一個物件都擁有一個引用計數(retain count)
  • 當物件被建立的時候,引用計數的值是1
  • 當傳送retain訊息時,該物件的引用計數加1,該物件的引用計數為2
  • 當向這個物件傳送release訊息時,該物件的引用計數減1
  • 當一個物件的引用計數為0時,系統自動呼叫dealloc方法,銷燬該物件

測試示例

  • 建立Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject @end
  • 建立Person.m
#import "Person.h"
@implementation Person
// 重寫dealloc方法
- (void) dealloc
{
    NSLog(@"Person dealloc"); 
    [super dealloc];
}
@end
  • 在main方法中呼叫
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @
autoreleasepool { Person *p = [[Person alloc] init]; NSLog(@"person的引用計數:%ld",[p retainCount]); // 列印結果1 [p retain]; // 保留引用 NSLog(@"person的引用計數:%ld",[p retainCount]); // 列印結果2 [p release]; // 釋放引用 NSLog(@"person的引用計數:%ld",[p retainCount]); // 列印結果1 [p release]
; // 列印結果Person dealloc,呼叫的是dealloc方法 } return 0; }

問題

1、 dealloc重寫報錯,retainCount方法無效

  • error log
'retainCount' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'retainCount'
  • 解決方法 在Bulid Settings中搜索Objective-C,找到Automatic Reference Counting,設定為No在這裡插入圖片描述

參考一篇文章注意ARC的使用事項:https://blog.csdn.net/iOSbird/article/details/50684325 1、ARCiOS5.0以後才支援,iOS7.0以後,強制使用ARC。 2、ARC Automatic Refercences Counting設定為YES。 3、原理:依然使用引用計數器來管理記憶體,只是引用計數器的操作方式不同,由程式設計師傳送訊息轉換為編譯器幫我們傳送訊息,會在合適的位置自動加入retain、release、autorelease訊息來進行計數管理,ARC是一種編譯期語法。 4、使用ARC:在ARC中,程式中不能出現retain、release、autorelease 在ARC中,程式不能在dealloc方法中顯示呼叫父類的dealloc方法,一切在MRC中和記憶體相關的操作,ARC中都不能使用。 5、強引用:在程式中定義的引用,預設就是強引用,所謂的強引用指向一個物件時,物件的引用計數器會自動加1,當引用超出作用域,物件的引用計數器自動減1。 定義強引用:__Strong Student* stu = [[Student alloc] init];當一個物件被引用指向時,此物件會隱式的retain一次,當強引用超出作用域時,指向的物件會隱式的release一次,引用在使用的時候,會根據作用域的範圍,自動做加1減1操作 6、弱引用:__weak Student* stu = [[Student alloc] init];僅僅就是指向物件,當一個弱引用指向的物件,未銷燬時,向物件傳送訊息,會自動變為強引用 當一個弱引用指向的物件被銷燬時,弱引用本身會自動的賦值為nil。 7、定義屬性的時候,記憶體管理的描述@property(nonatomic,strong) @property(nonatomic,weak)修改arcyes方法:點選專案名稱->在搜尋框輸入arc->找到Object-C Automatic Refercences Counting修改為yes。 8、其他修飾關鍵字@property(nonatomic,__unsafe__unretained)int age;__unsafe__unretained等同於assign,功能和weak幾乎一樣,唯一的不同,沒有"zeroing weak reference",通常用在基本資料型別__autoreleaseing用在方法的返回值,將返回值的物件放入到自動釋放池中。 9、dealloc方法在ARC中,dealloc方法不允許呼叫父類的dealloc方法,當然也不允許向任何物件傳送release訊息,所以說dealloc方法幾乎不用,在一些特殊情況下需要重寫dealloc方法: 1)、在類中使用了C語言中的函式malloc分配記憶體。 2)、在類中使用了C++語言中的函式new等方式建立記憶體空間 此時需要在dealloc中對這些特殊的空間進行釋放。 10、宣告引用自動置空, 在ARC下,如果定義了一個引用沒有賦值,編譯會自動的初始化設定引用為空值,Student* stu; 為了尊重C語言的規範,基本資料型別沒有初始化,依然是垃圾值。 11、MRCARC的混用,把MRC的程式碼轉換成ARC的程式碼,刪除記憶體管理操作(手動)xcode提供了自動將MRC轉換成ARC的功能,操作選單欄edit -> Refacotor(重構)-> Convert to Objective-C ARC。 在ARC專案中繼續使用MRC編譯的類,在編譯選項中標識MRC檔案即可-fno-objc-arc,在MRC專案中繼續使用ARC編譯的類在編譯選項中標識MRC檔案即可-fobjc-arc