iOS笔记 - Autorelease调用时机(对象出了方法就立即销毁?)
作者:互联网
Autorelease调用时机
1 - 我们先看代码
① 示例一:MRC模式
// - Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 -(void)dealloc{ 6 7 NSLog(@"person dealloc"); 8 [super dealloc]; 9 } 10 11 @end
// - ViewController.m
1 #import "ViewController.h" 2 #import "Person.h" 3 @implementation ViewController 4 5 - (void)viewDidLoad { 6 [super viewDidLoad]; 7 8 Person *p1 = [[[Person alloc] init] autorelease]; 9 NSLog(@"%s",__func__); 10 } 11 12 13 - (void)viewWillAppear:(BOOL)animated{ 14 15 [super viewWillAppear:YES]; 16 17 NSLog(@"%s",__func__); 18 } 19 20 -(void)viewDidAppear:(BOOL)animated{ 21 22 23 [super viewDidAppear:YES]; 24 NSLog(@"%s",__func__); 25 } 26 27 @end
日志信息:貌似和我们往常想象不一样(不是 Person对象出了自己的方法后就立即销毁了吗?)
② 示例二:ARC模式中依旧沿用示例一的代码(注意更改 Person的 dealloc方法),viewDidLoad中的 Person去掉 autorelease
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 Person *p1 = [[Person alloc] init]; 5 NSLog(@"%s",__func__); 6 }
日志信息:这一次和我们平常理解的一样(Person对象出了方法立刻销毁)
2 - ARC中对象出了方法立刻销毁,这是没问题的。问题就出现在 MRC中的 autorelease,因为它是和 Runloop有关联的
① 我们知道 iOS在主线程的 Runloop里注册了两个 observer
- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"%@",[NSRunLoop mainRunLoop]); }
日志信息:只截取 Observers
activities 是 kCFRunLoopBeforeTimers的枚举值
1 typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { 2 kCFRunLoopEntry = (1UL << 0), 3 kCFRunLoopBeforeTimers = (1UL << 1), // 2 4 kCFRunLoopBeforeSources = (1UL << 2), // 4 5 kCFRunLoopBeforeWaiting = (1UL << 5), // 32 6 kCFRunLoopAfterWaiting = (1UL << 6), // 64 7 kCFRunLoopExit = (1UL << 7), // 128 8 kCFRunLoopAllActivities = 0x0FFFFFFFU 9 };
我们看到两个观察者的 activities分别是 0x1 =1、0xa0 = 160 = 128+32,也就是一个监听 kCFRunLoopEntry,一个监听 kCFRunLoopBeforeWaiting和 kCFRunLoopExit
② 结论
第一个 Observer监听了 kCFRunLoopEntry事件,会调用 objc_autoreleasePoolPush()
第二个 Observer监听了 kCFRunLoopBeforeWaiting事件,会调用 objc_autoreleasePoolPop()、objc_autoreleasePoolPush();它还监听了 kCFRunLoopExit事件,会调用 objc_autoreleasePoolPop()
结语
1 - ARC中对象出了方法即被销毁,但对于 autorelease(MRC)它是由 Runloop来控制的,可能会是在某次 Runloop循环休眠之前调用了 release
标签:__,销毁,NSLog,void,iOS,Autorelease,Person,viewDidLoad,super 来源: https://www.cnblogs.com/self-epoch/p/16311633.html