是否保证在创建dealloc
实例的同一线程上调用NSObject
?例如,如果我在主线程上调用[[MyFluffyBunny alloc] init]
,则保证在主线程上调用dealloc
,或者在MyFluffyBunny
不再保留后,可以在任何线程上调用它?
我看到我的应用程序中的零星崩溃表明它无法保证,但我一直无法找到任何确认它的文档。
答案 0 :(得分:10)
对象在任何线程释放最后一个强引用时都会被释放。也就是说,无论什么线程在最后一次调用-release
。 期间实际上 -release
调用该对象被解除分配。
NSObject
协议中的documentation for the -release
method说:
减少接收者的引用计数。 ...当参考计数达到0时,接收方将收到
dealloc
消息。
高级内存管理编程指南:实用内存管理文章在reasons to not use -dealloc
to manage scarce resources:
在错误的线程上执行清理逻辑。
如果一个对象在意外的时间自动释放,它将在它碰巧进入的任何线程的自动释放池块中被释放。对于只能从一个线程触及的资源,这很容易致命。
< / LI> 醇>
答案 1 :(得分:2)
没有这样的保证,事实上,当使用KVO(以及OS X上的绑定)时,它会产生一些微妙的错误。
通过创建在[NSThread currentThread]
和init
期间记录dealloc
,然后运行以下代码的对象,您可以非常轻松地看到它的实际效果:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Testing *testing = [[Testing alloc] init];
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
NSLog(@"Use testing in background: %@", testing);
});
testing = nil;
return YES;
}
答案 2 :(得分:1)
我没有意识到文档中有一行说明了这一点,但这里有一些逻辑点:
如果您无法在某处找到保证,请假设它不存在。 (听起来你已经意识到了这一点,并且希望别人可以指出你能得到你想要答案的东西)
这个要求是不可能的,因为你可以在一个线程上构造一些东西,然后结束那个线程,然后让最后一个引用在某个其他线程的其他地方超出范围。此时不可能在旧线程上dealloc
,因为它不再存在。