我有一个由导航控制器提供的UIViewController。这个UIViewController以如下方式异步加载图像:
[self performSelectorInBackground:@selector(downloadData) withObject:nil];
- (void)downloadData {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
LocationDetails * details = [[LondonDatabase database] locationDetails : UniqueID];
NSData * imageData = [NSData dataWithContentsOfURL : [NSURL URLWithString : [details image]]];
picture = [[UIImage alloc ]initWithData:imageData];
[self performSelectorOnMainThread : @selector(updateUI) withObject : nil waitUntilDone : NO];
[pool release];
}
问题是,如果在上述方法执行时该视图控制器从堆栈弹出,则应用程序崩溃并显示错误:
bool _WebTryThreadLock(bool),0x61b3950:试图获取网页锁 从主线程或Web线程以外的线程。这可能 是从辅助线程调用UIKit的结果。崩溃 现在...
有人可以帮忙吗?
谢谢,
马丁
答案 0 :(得分:4)
使用NSThread并在视图控制器对象中保留该句柄。当视图控制器dealloc's时,取消线程(假设它还没有完成)。在downloadData中,在尝试访问视图控制器的元素之前检查线程是否未被取消。也就是说,如果线程已被取消,则返回。我有一个类似的问题,这就是我解决它的方式。
这是代码(将图像加载到自定义表格单元格中):
-(void)displayImage:(id)context { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIImage *image = (UIImage *)context; [spinner stopAnimating]; brandImage.image = image; [brandImage setNeedsDisplay]; [pool release]; } -(void)fetchImage:(id)context { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *url = (NSString *)context; if ([[NSThread currentThread] isCancelled]) return; UIImage *image = [ArtCache imageForURL:url]; if (![[NSThread currentThread] isCancelled]) { [self performSelectorOnMainThread:@selector(displayImage:) withObject:image waitUntilDone:NO]; } [pool release]; } -(void)showBrandImageURL:(NSString *)url { [spinner startAnimating]; brandImage.image = nil; if (imageLoadThread) { [imageLoadThread cancel]; [imageLoadThread release]; } imageLoadThread = [[NSThread alloc] initWithTarget:self selector:@selector(fetchImage:) object:url]; [imageLoadThread setThreadPriority:0.8]; [imageLoadThread start]; }
这些是自定义表格单元格类中的3种方法。最后一个是来自cellForRowAtIndexPath:
的呼叫。另外两个支持被称为的那个。