Autorelease对象的释放时机

参考sunnyxx的黑幕背后的Autorelease

在看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]); // <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
}

输出结果中,在viewDidLoadviewWillAppearrefStr都是有值的,而viewDidAppear中就已经释放掉了. 还可以看到在三个方法中 RunLoop 的内存地址都是相同的,但是在viewDidLoadviewWillAppear中 RunLoop 的 mode 是 UIInitializationRunLoopMode,而在viewDidAppear中是kCFRunLoopDefaultMode. 注意:

当 RunLoop 切换 mode 时,只能退出后再重新进入.

所以,在执行viewDidAppear时,会把上一个 RunLoop 中的releapool对象释放掉.这也就是viewDidAppear中输出为 null 的原因.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容