參考sunnyxx的黑幕背后的Autorelease
在看sunnyxx大大的文章時(shí),發(fā)現(xiàn)有個(gè)部分理解的不是很清楚,然后自己做了個(gè)補(bǔ)充,權(quán)當(dāng)筆記以備后用
在沒有手動(dòng)干預(yù)Autorelease Pool的情況下,Autorelease對(duì)象是在當(dāng)前的runloop迭代結(jié)束時(shí)釋放的甜滨,而它能夠釋放的原因是系統(tǒng)在每個(gè)runloop迭代中都加入了自動(dòng)釋放池Push和Pop
__weak id refStr = nil;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = [NSString stringWithFormat:@"runloop test"];
refStr = str;
NSLog(@"%s=======%@",__func__,[NSRunLoop currentRunLoop]);//CFRunLoop 0x174178600 [0x1a9b45bb8]> current mode = UIInitializationRunLoopMode
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSLog(@"str in %s: %@",__func__,refStr); //str in -[ViewController viewWillAppear:]: runloop test
NSLog(@"%s=======%@",__func__,[NSRunLoop currentRunLoop]); // <CFRunLoop 0x174178600 [0x1a9b45bb8]> current mode = UIInitializationRunLoopMode,
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
NSLog(@"str in %s: %@",__func__,refStr); // str in -[ViewController viewDidAppear:]: (null)
NSLog(@"%s=======%@",__func__,[NSRunLoop currentRunLoop]);//CFRunLoop 0x174178600 [0x1a9b45bb8]> current mode = kCFRunLoopDefaultMode
}
輸出結(jié)果中,在viewDidLoad
和viewWillAppear
中refStr
都是有值的,而viewDidAppear
中就已經(jīng)釋放掉了. 還可以看到在三個(gè)方法中 RunLoop 的內(nèi)存地址都是相同的,但是在viewDidLoad
和viewWillAppear
中 RunLoop 的 mode 是 UIInitializationRunLoopMode
,而在viewDidAppear
中是kCFRunLoopDefaultMode
. 注意:
當(dāng) RunLoop 切換 mode 時(shí),只能退出后再重新進(jìn)入.
所以,在執(zhí)行viewDidAppear
時(shí),會(huì)把上一個(gè) RunLoop 中的releapool對(duì)象釋放掉.這也就是viewDidAppear
中輸出為 null 的原因.