__weak NSString *string_weak_ = nil;
- (void)viewDidLoad {
[super viewDidLoad];
// 场景 1
NSString *string = [NSString stringWithFormat:@"leichunfeng"];
string_weak_ = string;
// 场景 2
// @autoreleasepool {
// NSString *string = [NSString stringWithFormat:@"leichunfeng"];
// string_weak_ = string;
// }
// 场景 3
// NSString *string = nil;
// @autoreleasepool {
// string = [NSString stringWithFormat:@"leichunfeng"];
// string_weak_ = string;
// }
NSLog(@"string: %@", string_weak_);
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"string: %@", string_weak_);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"string: %@", string_weak_);
}
// 场景 1
2015-05-30 10:32:20.837 AutoreleasePool[33876:1448343] string: leichunfeng
2015-05-30 10:32:20.838 AutoreleasePool[33876:1448343] string: leichunfeng
2015-05-30 10:32:20.845 AutoreleasePool[33876:1448343] string: (null)
// 场景 2
2015-05-30 10:32:50.548 AutoreleasePool[33915:1448912] string: (null)
2015-05-30 10:32:50.549 AutoreleasePool[33915:1448912] string: (null)
2015-05-30 10:32:50.555 AutoreleasePool[33915:1448912] string: (null)
// 场景 3
2015-05-30 10:33:07.075 AutoreleasePool[33984:1449418] string: leichunfeng
2015-05-30 10:33:07.075 AutoreleasePool[33984:1449418] string: (null)
2015-05-30 10:33:07.094 AutoreleasePool[33984:1449418] string: (null)
https://juejin.im/post/5a66e28c6fb9a01cbf387da1
本文主要探讨两个方面:(1)autorelease对象到底是合适被析构的?(2)OC内部是如何处理一个被autorelease掉的对象的?
(1)autorelease对象到底是何时被析构的?
这个问题说难不难,但说简单也不简单。我们还是先看一类熟悉的不能再熟悉的代码吧:
1 - (void)viewDidLoad {
2 [super viewDidLoad];
3 NSArray *localArr = [NSArray arrayWithObject:@"Weng Zilin"];//这是一个局部对象,封装了autorelease方法
4 }
请问,localArr这个局部变量何时被析构呢?很多人会回答:“出了作用域,也就是花括号之后就会被回收”。但遗憾的是,事实并非你想象的那般顺利。下面我通过几行代码向你证明,localArr出了作用于依旧活得好好的:(ARC环境下)
__weak id objTrace;
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *localArr = [NSArray arrayWithObject:@"Weng Zilin"];//这是一个局部对象,封装了autorelease方法
} - (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"viewWillAppear__localArr:%@", objTrace);
} - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"viewWillAppear__localArr:%@", objTrace);
}
在ARC环境下我用一个__weak类型来追踪localArr的释放时机,__weak并不会对localArr增加引用计数,因此不干扰其释放,log显示如下:
我们发现,localArr在viewWillAppear还活着,在DidAppear已经挂了。这说明了一件事:autorelease并不是根据作用域来决定释放时机的。那到底是依据什么呢?答案是:runloop。
runloop不在本文讨论范围内,感兴趣的同学请自行查阅资料,传送门点这里。简单说,runloop就是iOS中的消息循环机制,当一个runloop结束时系统才会一次性清理掉被autorelease处理过的对象,其实本质上说是在本次runloop迭代结束时清理掉被本次迭代期间被放到autorelease pool中的对象的。至于何时runloop结束并没有固定的duration! http://www.cnblogs.com/wengzilin/p/4351187.html