有没有好奇过, 主动开释池会耽误开释对象,那到底哪些对象会到场制动开释池呢?
先科普一下main函数里的结构
从前的main函数的结构
现在的main函数结构
发现有啥不同了不?
区别就在于
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
老项目结构放在了@autoreleasepool {}内里
为啥新项目结构厥后苹果选择放在@autoreleasepool {}外貌了呢?
好比如下情况,这个o对象就无法开释了
int main(int argc, char * argv[]) { @autoreleasepool { objc *o = [objc create]; /// 假如该对象会到场主动开释池,此时o对象将永久无法开释了 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}回归正题
- 方法1
viewDidLoad弱持有对象,viewWillAppear访问
由于这两个方法是在同一个runloop循环中,假如到场了主动开释池,在viewWillAppear还是可以访问到的。
注(进入runloop会天生一个主动开释池,退出一个runloop循环会开释主动开释池及开释池里的对象)
上代码
@interface ViewController ()@property (weak, nonatomic) NSMutableArray *arr;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *array = [[NSMutableArray alloc] init]; self.arr = array;}- (void)viewWillAppearBOOL)animated { [super viewWillAppear:animated]; NSLog(@"self.arr %@", self.arr);}
- 方法2
闭幕大招
通过_objc_autoreleasePoolPrint打印注册到主动开释池里的对象
上代码
有一个对象到场了主动开释池(2 releases pending, 此中有个哨兵对象)
怀疑不恻隐况下,结果也会不一样,同样的代码,换个情况,有两个数组到场了主动开释池
网上很多表明
什么objc_autoreleaseReturnValue,然后objc_retainAutoreleasedReturnValue(https://www.jianshu.com/p/5ec8fdef8e7e)的就不会到场主动开释池(自行百度google),但还是得自己验证,每个版本都有大概有变革,不可尽信书(何况网上的文章还不是书),也不可不看书。
现在来分析下_objc_autoreleasePoolPrint这个是否有可信度呢?
上源码
void _objc_autoreleasePoolPrint(void){ AutoreleasePoolPage::printAll();}进入printAll(); 关键代码,一页一页遍历
for (page = coldPage(); page; page = page->child) { page->print();}然后我们在看下每页的打印page->print();
################ POOL 0x10400a038 打印的正式占位对象
_objc_inform("[%p] %#16lx %s", p, (unsigned long)*p, object_getClassName(*p));打印的正是
objc[38018]: [0x10400a040] 0x100c65300 __NSArrayM
objc[38018]: [0x10400a048] 0x100c65380 __NSArrayM
格言:不可尽信书,也不可不看书,看完此文章还需亲自己亲自验证才气得自己的明确。 |