【问题标题】:Asynchronous Loading of Image - Crashing If Dealloced图像的异步加载 - 如果解除分配则崩溃
【发布时间】:2011-04-15 19:19:59
【问题描述】:

我有一个由导航控制器提供的 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: 试图获取网络锁 来自除主线程或网络线程之外的线程。这可能 是从辅助线程调用 UIKit 的结果。崩溃 现在...

谁能帮忙?

谢谢,

马丁

【问题讨论】:

    标签: iphone objective-c cocoa-touch asynchronous sdk


    【解决方案1】:

    使用 NSThread 并在视图控制器对象中保留一个句柄。当视图控制器dealloc的,取消线程(假设它还没有完成)。在 downloadData 中,在尝试访问视图控制器的元素之前检查线程是否被取消。也就是说,如果线程已经被取消,就直接返回。我有一个类似的问题,这就是我解决它的方法。

    这是代码(将图像加载到自定义表格单元格中):

    -(void)displayImage:(id)context { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIImage *image = (UIImage *)context; [微调停止动画]; 品牌形象.形象 = 形象; [brandImage setNeedsDisplay]; [池释放]; } -(void)fetchImage:(id)context { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *url = (NSString *)context; if ([[NSThread currentThread] isCancelled]) 返回; UIImage *image = [ArtCache imageForURL:url]; if (![[NSThread currentThread] isCancelled]) { [self performSelectorOnMainThread:@selector(displayImage:) withObject:image waitUntilDone:NO]; } [池释放]; } -(void)showBrandImageURL:(NSString *)url { [微调开始动画]; 品牌形象.形象=无; 如果(图像加载线程){ [imageLoadThread 取消]; [imageLoadThread 发布]; } imageLoadThread = [[NSThread alloc] initWithTarget:self 选择器:@selector(fetchImage:) object:url]; [imageLoadThread setThreadPriority:0.8]; [imageLoadThread 开始]; }

    这些是自定义表格单元格类中的 3 个方法。最后一个是来自cellForRowAtIndexPath: 的那个。另外两个支持被调用的那个。

    【讨论】:

    • @Ohnomycoco:不,您可以省略线程优先级指令。我们使用的表格单元格很复杂,准备时间很长。我们将图像加载移到后台任务中,以防它产生任何影响,我们降低了线程的优先级以加快 UI 的其余部分(和表格加载)。使操作成为线程是一个巨大的胜利。更改线程优先级的好处不是那么明显。 :-)
    猜你喜欢
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多