OC 30 day
為什麼放這張圖?應為我覺得MRC就像是古老的儀式。既然MRC已經沒什麼人在用了,為什麼還要學?因為ARC的機制是源自於MRC,因此要用ARC必須要再會使用MRC的基礎下。
iOS5開始,Xcode4.2開始支持ARC。 Xcode7 默認支持ARC開發。默認使用的開發方式就是ARC模式。
ARC的運作機制,當對象的引用計數器變為0的時候,系統會自動回收對象,在系統回收對象的時候,會自動調用對象的dealloc方法。
到project裡的build settings 裡搜尋 Automatic。可以找到OC 的ARC全名,將它關閉就可以了。
但是我有些地方想用ARC,有些地方想用MRC怎麼辦?
全局的設定可以從build Setting 設定,而特定的檔案再從Build Phases設定。
感謝 swift線上讀書會的工程屍解答
ARC的運作機制,當對象的引用計數器變為0的時候,系統會自動回收對象,在系統回收對象的時候,會自動調用對象的dealloc方法。
我們來了解dealloc如何運作的。
重寫dealloc方法的規範:
必須要調用父類dealloc方法,並且要放在最後一句的地方。
#import "Person.h"
@interface Person()
//@property (nonatomic,copy) NSString *message;
@end
@implementation Person
// 只要這個方法被執行,就代表這個對象被回收了
- (void)dealloc
{
NSLog(@"%@",_name);
[super dealloc];
}
- (void)sayHi{
NSLog(@"Hi");
}
@end
我們先來實驗看看,當我們實例化Person這個對象時,引用計數器是否有加1。
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
NSUInteger count = [p1 retainCount];
NSLog(@"count = %lu",count);
}
}
結果打印出來,確實引用數有加1。
我在Person裡面加入了dealloc的方法,我們來試試看回收的效果吧。
引用計數器-1 [p1 release];
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
p1.name = @"猴子";
NSUInteger count = [p1 retainCount];
NSLog(@"count = %lu",count);
[p1 release];
}
}
我們可以看到引數為零的時候,對象就被清空了。
我們再來嘗試手動引用計數器+1。[p1 retain];
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
p1.name = @"猴子";
NSUInteger count = [p1 retainCount];
[p1 retain];
NSLog(@"count = %lu",count);
[p1 release];
}
}
奇怪猴子怎麼沒有去了?為什麼對象沒有回收?
為對象發送release消息,並不是回收對象,而是讓對象引用計數器-1,當對象的引用計數器的值為0的時候。對象才會被系統立即回收。
當多一個人使用這個對象時,應該為這個對象發送retain消息。
什麼時候為對象發送release消息。
當少一個人使用這個對象時,應該為這個對象發送release消息。
只要dealloc這個方法執行,就會釋放這個對象。
所以在ARC機制下,retain release dealock這些方法無法調用。
內存管理的原則。
有對象的創建,就要匹配一個release。
誰retain誰就release。
在寫專案時,估計還是會用ARC。但是我認為因為ARC的機制是源自於MRC,因此要用ARC必須要再會使用MRC的基礎下。