dealloc в фоновом потоке - PullRequest
5 голосов
/ 30 апреля 2010

Ошибка вызова dealloc на UIViewController из фонового потока? Кажется, что UITextView (может?) В конце концов вызовет _WebTryThreadLock, что приводит к:

bool _WebTryThreadLock (bool): попытался получить веб-блокировку из потока кроме основного потока или веб-потока. Это может быть результатом вызова UIKit из вторичного потока.

Справочная информация: у меня есть подкласс NSOperation, который принимает selector и target объект для уведомления.

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

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

Если UIViewController уже отклонен, когда NSOperation приступает к работе, то вызов release вызывает его dealloc в фоновом потоке.

Ответы [ 4 ]

9 голосов
/ 25 июня 2014

Да, ошибка при создании UIViewController в фоновом потоке (или очереди). В UIKit dealloc не является потокобезопасным. Это явно описано в Apple TN2109 doc:

Когда вторичный поток сохраняет целевой объект, вы должны убедиться, что поток освобождает эту ссылку, прежде чем основной поток выпустит свою последнюю ссылку на объект. Если вы этого не сделаете, последняя ссылка на объект освобождается вторичным потоком, что означает, что метод -dealloc объекта выполняется в этом вторичном потоке. Это проблематично, если метод -dealloc объекта выполняет действия, которые небезопасны для вторичного потока, что является общим для объектов UIKit, таких как контроллер представления.

6 голосов
/ 30 апреля 2010

Простое правило: ошибочно делать что-либо на UI* из фонового потока.

3 голосов
/ 26 мая 2010

Во втором посте была полезная информация, но их ответ мне не помог.

UIWebView в многопоточном ViewController

Также кажется, что это может быть решено в iPhone OS 4, но не уверен.

В итоге я не выпустил свой UIWebView в разлочке контроллера, когда [NSThread isMainThread] было НЕТ. Скорее протекает, чем падает (пока не найду лучшее решение).

2 голосов
/ 26 мая 2010

Ошибка вызывать dealloc для чего-либо в любое время. Вы должны только когда-либо называть релиз.

Вы не должны обращаться к экземплярам, ​​связанным с пользовательским интерфейсом, из фонового потока. Это включает в себя использование методов получения, потому что они могут изменять вещи внутри. Тем не менее, сохранение и освобождение являются потокобезопасными для любого объекта в любое время при условии соблюдения нормальных правил сохранения и освобождения. К экземплярам, ​​связанным с пользовательским интерфейсом, относится любой объект, на который ссылается активный UIView или UIViewController.

executeSelectorOnMainThread не делает ничего, кроме как удерживает объект до тех пор, пока он не попадет в основной поток. Безопасно вызывать любой объект, связанный с пользовательским интерфейсом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...