У меня есть UIViewController, и в этом контроллере я получаю изображение из источника URL. Изображение извлекается в отдельном потоке, после чего пользовательский интерфейс обновляется в основном потоке. Этот контроллер отображается как страница в родительском объекте UIScrollView, который реализован для освобождения контроллеров, которые больше не отображаются.
Когда поток завершает выборку содержимого до выпуска UIViewController, все работает нормально - но когда пользователь переходит на другую страницу до завершения потока, контроллер освобождается, и единственный дескриптор контроллера принадлежит потоку, создающему releaseCount контроллера равно 1. Теперь, как только поток истощает NSAutoreleasePool, контроллер получает релизы, потому что releaseCount становится равным 0. В этот момент мое приложение падает, и я получаю следующее сообщение об ошибке:
bool _WebTryThreadLock (bool), 0x4d99c60: Пытался получить веб-блокировку из потока, отличного от основного или веб-потока. Это может быть результатом обращения к UIKit из вторичного потока. Авария сейчас ...
Обратная трассировка показывает, что приложение вызвало сбой при вызове [super dealloc], и это имеет смысл, так как функция dealloc должна была запускаться потоком, когда пул очищался. У меня вопрос, как я могу преодолеть эту ошибку и освободить контроллер без утечки памяти?
Одним из решений, которое я попытался, было вызвать [self retain] до опустошения пула, чтобы 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];
}
}
Пожалуйста, помогите! Заранее спасибо.