背景线程上的dealloc

时间:2010-04-30 16:47:28

标签: iphone objective-c memory-management

从后台线程调用dealloc上的UIViewController是错误的吗?似乎UITextView(可以?)最终调用_WebTryThreadLock会导致:

  

bool _WebTryThreadLock(bool):试图从线程获取Web锁   除主线程或网络线程之外。这可能是打电话的结果   从辅助线程到UIKit。

背景:我有一个子类NSOperation,需要selectortarget个对象通知。

-(id)initWithTarget:(id)target {
   if (self = [super init]) {
      _target = [target retain];
   }
   return self;
}

-(void)dealloc {
   [_target release];
   [super dealloc];
}

如果在UIViewController开始运行时NSOperation已被解除,则对release的调用会在后台线程上触发dealloc

4 个答案:

答案 0 :(得分:9)

是的,在后台线程(或队列)中释放UIViewController是一个错误。在UIKit中,dealloc不是线程安全的。这在Apple的TN2109 doc:

中有明确说明
  

当辅助线程保留目标对象时,必须确保线程在主线程释放其对象的最后一个引用之前释放该引用。如果不这样做,则辅助线程将释放对象的最后一个引用,这意味着对象的-dealloc方法在该辅助线程上运行。如果对象的-dealloc方法执行在辅助线程上不安全的事情,这是有问题的,这对UIKit对象(如视图控制器)来说很常见。

答案 1 :(得分:6)

简单的规则是从后台线程UI*上执行任何是错误的。

答案 2 :(得分:3)

这里的第二篇文章提供了有用的信息,但他们的答案对我不起作用。

UIWebView in multithread ViewController

似乎这可能已在iPhone OS 4中得到解决,但不确定。

当[NSThread isMainThread]为NO时,我最终没有在控制器的dealloc中释放我的UIWebView。宁愿泄漏而不是崩溃(直到我得到更好的解决方案)。

答案 3 :(得分:2)

在任何时候调用dealloc都是错误的。你应该只打电话给释放。

您不应该从后台线程访问任何UI相关实例。这包括使用getter方法,因为它们可能会在内部修改内容。但是,只要遵循保留和释放的常规规则,保留和释放在任何时候都对任何对象都是线程安全的。 UI相关实例包括活动UIView或UIViewController引用的任何对象。

performSelectorOnMainThread除了保留对象直到它到达主线程之外什么都不做。调用任何与UI相关的对象是安全的。