У меня есть UIViewController, и в этом контроллере я получаю изображение из источника URL. Изображение загружается в отдельный поток, после которого пользовательский интерфейс обновляется в основном потоке. Этот контроллер отображается в виде страницы в родительском элементе UIScrollView, который предназначен для выпуска контроллеров, которые больше не отображаются.iPhone: проблемы с выпуском UIViewController в многопоточной среде
Когда поток заканчивает получение содержимого до выпуска UIViewController, все работает нормально - но когда пользователь прокручивается на другую страницу до завершения потока, контроллер освобождается, а единственный дескриптор контроллера принадлежит потоку releaseCount контроллера равен 1. Теперь, как только поток истощает NSAutoreleasePool, контроллер получает релизы, потому что releaseCount становится 0. в этот момент моего сбой приложения и я получаю следующее сообщение об ошибке:
Их _WebTryThreadLock (bool), 0x4d99c60: попытался получить веб-блокировку из потока, отличного от основного потока или веб-потока. Это может быть результатом вызова UIKit из вторичного потока. Сбой сейчас ...
Обратный ход показывает, что приложение потерпело крах при вызове [super dealloc], и это имеет смысл, поскольку функция dealloc должна была быть вызвана нитью при сливе пула. Мой вопрос в том, как я могу преодолеть эту ошибку и освободить контроллер без утечки памяти?
Одно из решений, что я попытался было назвать [самостоятельно сохранить] до бассейна сливают так, что retainCount не падает до нуля, а затем, используя следующий код, чтобы освободить контроллер в основном потоке:
[self performSelectorOnMainThread:@selector(autorelease)
withObject:nil waitUntilDone:NO];
К сожалению, это не сработало. Ниже приведена функция, которая выполняется на резьбе:
- (void)thread_fetchContent {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *imgURL = [NSURL URLWithString:@"http://www.domain.com/image.png"];
// UIImage *imgHotspot is declared as private - The image is retained
// here and released as soon as it is assigned to UIImageView
imgHotspot = [[[UIImage alloc] initWithData:
[NSData dataWithContentsOfURL: imgURL]] retain];
if ([self retainCount] == 1) {
[self retain]; // increment retain count ~ workaround
[pool drain]; // drain pool
// this doesn't work - i get the same error
[self performSelectorOnMainThread:@selector(autorelease)
withObject:nil waitUntilDone:NO];
}
else {
// show fetched image on the main thread - this works fine!
[self performSelectorOnMainThread:@selector(showImage)
withObject:nil waitUntilDone:NO];
[pool drain];
}
}
Пожалуйста, помогите! Заранее спасибо.
Спасибо! Подход NSOperation был большой помощью - я посмотрел ссылку, которую вы предоставили, и учебник по адресу http: //www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/- он решил мою проблему :) –