在看sunnyxx大大的文章時,發現有個部分了解的不是很清楚,然後自己做了個補充,權當筆記以備後用
在沒有手動幹預Autorelease Pool的情況下,Autorelease對象是在目前的runloop疊代結束時釋放的,而它能夠釋放的原因是系統在每個runloop疊代中都加入了自動釋放池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]); // 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
}
輸出結果中,在viewDidLoad和viewWillAppear中refStr都是有值的,而viewDidAppear中就已經釋放掉了. 還可以看到在三個方法中 RunLoop 的記憶體位址都是相同的,但是在viewDidLoad和viewWillAppear中 RunLoop 的 mode 是 UIInitializationRunLoopMode,而在viewDidAppear中是kCFRunLoopDefaultMode. 注意:
當 RunLoop 切換 mode 時,隻能退出後再重新進入.
是以,在執行viewDidAppear時,會把上一個 RunLoop 中的releapool對象釋放掉.這也就是viewDidAppear中輸出為 null 的原因.