ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

iOS笔记 - Autorelease调用时机(对象出了方法就立即销毁?)

2022-05-26 02:01:00  阅读:170  来源: 互联网

标签:__ 销毁 NSLog void iOS Autorelease Person viewDidLoad super


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有