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、ARC
是iOS5.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)
修改arc
為yes
方法:點選專案名稱->在搜尋框輸入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、MRC
和ARC
的混用,把MRC
的程式碼轉換成ARC
的程式碼,刪除記憶體管理操作(手動)xcode
提供了自動將MRC
轉換成ARC
的功能,操作選單欄edit -> Refacoto
r(重構)-> Convert to Objective-C ARC
。 在ARC
專案中繼續使用MRC
編譯的類,在編譯選項中標識MRC
檔案即可-fno-objc-arc
,在MRC
專案中繼續使用ARC
編譯的類在編譯選項中標識MRC
檔案即可-fobjc-arc
。