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

标签 ios objective-c objective-c-blocks quartz-2d

我有一个大的 jpeg 图像,我想在我的 opengl 引擎中异步加载到图 block 中。 如果在主线程上完成,一切都会很好,但速度很慢。

当我尝试将图 block 加载到 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];

}

最佳答案

我终于发现我的问题了...

我已经阅读了 Quartz2D 文档,看来我们不应该再使用 CGDataProviderCreateWithData 和 CGI​​mageCreateWithJPEGDataProvider 了。我猜想那里的用法不是线程安全的。

根据文档的建议,我现在使用 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);

关于ios - 在后台线程中读取 CGImageRef 会使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16672506/

相关文章:

ios - 从 Collection View Xcode 中删除 Collection View Cell

ios - 如何禁用 MGLAnnotation 的用户交互?

ios - 如何将图像添加到 UITableViewHeaderFooterView?

iphone - 在 TableView 中重新排序单元格时获取索引路径?

ios id 不转换为 nsinteger

ios - 我是否应该在每次使用 block 时削弱自己

ios - 动态改变UIPageControl.appearance的点的背景颜色

android - 是否可以通过 IOS 或 Android 商店进行深度链接(将数据从 url 传递到应用程序安装)

ios - 检查字符串是否已经存在并在数组中的字符串中添加一个数字作为后缀?

ios - 如何返回 enumerateObjectsUsingBlock 找到的项目?