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]); //   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 的原因.

你可能感兴趣的:(Autorelease对象的释放时机)