是否保证在创建对象的同一线程上调用dealloc?

时间:2015-09-26 17:26:08

标签: objective-c

是否保证在创建dealloc实例的同一线程上调用NSObject?例如,如果我在主线程上调用[[MyFluffyBunny alloc] init],则保证在主线程上调用dealloc,或者在MyFluffyBunny不再保留后,可以在任何线程上调用它?

我看到我的应用程序中的零星崩溃表明它无法保证,但我一直无法找到任何确认它的文档。

3 个答案:

答案 0 :(得分:10)

对象在任何线程释放最后一个强引用时都会被释放。也就是说,无论什么线程在最后一次调用-release。 期间实际上 -release调用该对象被解除分配。

NSObject协议中的documentation for the -release method说:

  

减少接收者的引用计数。 ...当参考计数达到0时,接收方将收到dealloc消息。

高级内存管理编程指南:实用内存管理文章在reasons to not use -dealloc to manage scarce resources

中包含了这一内容
  
      
  1. 在错误的线程上执行清理逻辑。

         

    如果一个对象在意外的时间自动释放,它将在它碰巧进入的任何线程的自动释放池块中被释放。对于只能从一个线程触及的资源,这很容易致命。

    < / 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,因为它不再存在。