2012-01-22 20 views
1

我正在处理iOS项目,该项目从后台线程中的URL加载UIImages并将其显示在水平分页滚动视图中。这种行为应该模仿iPhone的本地照片库应用程序。我有,我相信应该工作的方式的一切设置,但在主UI图形上下文绘图的UIImages,我偶尔会看到这条消息打印出来控制台:在后台线程中加载UIImage导致ImageIO错误

ImageIO: <ERROR> CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedImageBlockData: bad readSession [0x685e590] 

尽管这样的错误,看来该应用程序功能完好,并且图像按预期绘制。我应该简单地忽略这个“错误”,还是应该改变我的后台线程加载图像的方法?目前,我使用的UIImage initWithData:方法装载在后台线程中的图像:

- (void)backgroundLoadThread:(NSURL *)url { 
    @autoreleasepool { 
     NSData * imageData = [NSData dataWithContentsOfURL:url]; 
     UIImage * theImage = [[UIImage alloc] initWithData:imageData]; 
     if ([[NSThread currentThread] isCancelled]) { 
#if !__has_feature(objc_arc) 
      [theImage release]; 
#endif 
      return; 
     } 
     [self performSelectorOnMainThread:@selector(loadComplete:) 
           withObject:theImage waitUntilDone:NO]; 
    } 
} 

loadComplete:方法简单地保持为一个实例变量,其在视图的drawRect:方法以后绘制传递的图像。在drawRect:中,我使用的是UIImage drawInRect:方法,它似乎是控制台中错误消息的执行者。但是,使用CGContextDrawImage绘制图像的底层CGImageRef仍会导致相同的错误。完整的源代码可以在这个项目的Github存储库中找到,文件为ANAsyncImageView.m

编辑:我现在已经改变后台线程从文件加载CGImage,然后回调到主线程,传递CGImageRef使用免费桥接。不幸的是,这仍然会产生同样的问题,向我证明UIImage的imageWithCGImage:必须以某种方式保留对原始CGImage的引用。查看上面链接到Github存储库的代码:

NSData * imageData = [NSData dataWithContentsOfURL:url]; 
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)imageData); 
CGImageRef loaded = CGImageCreateWithPNGDataProvider(provider, NULL, false, kCGRenderingIntentDefault); 
CGDataProviderRelease(provider); 

id imageObj = (id)loaded;   
[self performSelectorOnMainThread:@selector(loadComplete:) withObject:imageObj waitUntilDone:NO]; 
CGImageRelease(loaded); 
+0

不管线程是否被取消,你不应该释放该图像吗? 'performSelectorOnMainThread:withObject:waitUntilDone:'会为你保留和释放对象,所以你不必担心它会从你的下面消失。 –

+0

请先看到这个问题:https://stackoverflow.com/a/26562349/1084174 –

回答

6

UIKit不是线程安全的类。因此,你不应该从后台调用UIImage。

而不是创建UIImages,将您的图像文件呈现为CGImageRefs。您可以将其中的一个传递回主线程并从中生成UIImage(将图像解压缩的负担移至背景,您仍然会受益)。

+0

我改变了它,所以后台线程现在加载一个CGImageRef,并将其传递给主线程,主线程又通过它使用它创建一个UIImage 'imageWithCGImage:'。相同的消息仍然在控制台中打印出来。 –

+0

既然如此,这个答案根本不能解决问题。 –

+0

你在设备上还是在模拟器上运行?不管你有没有得到同样的错误? – isaac

相关问题