【发布时间】:2010-05-30 08:44:40
【问题描述】:
我有一个 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];
}
}
请帮忙!提前谢谢你。
【问题讨论】:
标签: iphone memory-leaks nsautoreleasepool