在后台线程中读取CGImageRef使应用程序崩溃

在后台线程中读取CGImageRef使应用程序崩溃

问题描述:

我有一个很大的jpeg图像,我想在我的opengl引擎中异步加载tile。 如果它在主线程上完成但一切都很好,但速度很慢。在后台线程中读取CGImageRef使应用程序崩溃

当我尝试将加载在NSOperationBlock上的图块加载时,它总是在尝试访问我以前在主线程中加载的共享图像数据指针时崩溃。

必须有一些我不能与后台操作,因为我假设我可以访问我在主线程上创建的内存部分。

我尝试做的是以下几点:

@interface MyViewer 
{ 
} 
@property (atomic, assign) CGImageRef imageRef; 
@property (atomic, assign) CGDataProviderRef dataProvider; 
@property (atomic, assign) int loadedTextures; 
@end 

... 

- (void) loadAllTiles:(NSData*) imgData 
{ 
    queue = [[NSOperationQueue alloc] init]; 
    //Loop for Total Number of Textures 

    self.dataProvider = CGDataProviderCreateWithData(NULL,[imgData bytes],[imgData length],0); 
    self.imageRef = CGImageCreateWithJPEGDataProvider(self.dataProvider, NULL, NO, kCGRenderingIntentDefault); 

    for (int i=0; i<tileCount; i++) 
    { 

     // I also tried this but without luck 
     //CGImageRetain(self.imageRef); 
     //CGDataProviderRetain(self.dataProvider); 

     NSBlockOperation *partsLoading = [[NSBlockOperation alloc] init]; 
     __weak NSBlockOperation *weakpartsLoadingOp = partsLoading; 
     [partsLoading addExecutionBlock:^{ 

      TamTexture2D& pTex2D = viewer->getTile(i); 

      CGImageRef subImgRef = CGImageCreateWithImageInRect(self.imageRef, CGRectMake(pTex2D.left, pTex2D.top, pTex2D.width, pTex2D.height)); 

      //!!!Its crashing here!!! 
      CFDataRef cgSubImgDataRef = CGDataProviderCopyData(CGImageGetDataProvider(subImgRef)); 
      CGImageRelease(subImgRef); 

      ... 
      }]; 

     //Adding Parts loading on low priority thread. Is it all right ???? 
     [partsLoading setThreadPriority:0.0]; 
     [queue addOperation:partsLoading]; 

} 
+0

提示:UI更新必须在主运行循环来完成。您可以在后台线程中执行处理,但在实际更新UI时强制执行主循环。 –

+0

是的,我实际上在我的例子中抽象了这部分代码,thx – AkademiksQc

+0

你的一个参考是否为NULL? – CodaFi

我终于找到了我的问题......

我已阅读Quartz2D doc和我们似乎不应该使用CGDataProviderCreateWithData和CGImageCreateWithJPEGDataProvider了。我想那里的用法不是线程安全的。

正如所建议的医生,我现在用的CGImageSource API这样的:

self.imageSrcRef = CGImageSourceCreateWithData((__bridge CFDataRef)imgData, NULL); 

// get imagePropertiesDictionary 
CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(m_imageSrcRef,0, NULL); 

self.imageRef = CGImageSourceCreateImageAtIndex(m_imageSrcRef, 0, imagePropertiesDictionary); 
+0

我正在运行与CGImageCreateWithJPEGDataProvider无关的线程问题。但是我找不到表示它不是线程安全的Apple文档,您指的是。你还能找到它吗? – iljawascoding

+0

我没有阅读CGImageCreateWithJPEGDataProvider不是线程安全的任何地方,它只是我在测试后做出的一个结论...除非我做错了什么,但我看不到...只是切换到ImageIO解决了我的问题 – AkademiksQc