我有一个 UIViewController,在那个控制器中,我从 URL 源获取图像。图像在一个单独的线程中获取,然后在主线程上更新用户界面。此控制器显示为 UIScrollView 父页面中的页面,该页面用于释放不再可见的控制器。
当线程在 UIViewController 释放之前完成获取内容时,一切正常 - 但是当用户在线程完成之前滚动到另一个页面时,控制器被释放并且控制器的唯一句柄由创建控制器 releaseCount 的线程拥有等于 1。现在,一旦线程耗尽 NSAutoreleasePool,控制器就会获得释放,因为 releaseCount 变为 0。此时,我的应用程序崩溃并且我收到以下错误消息:
bool _WebTryThreadLock(bool), 0x4d99c60: 试图从主线程或web线程以外的线程获取web lock。这可能是从辅助线程调用 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];
}
}
请帮忙!先感谢您。