Reading CGImageRef in a background thread crashes the app

空扰寡人 提交于 2019-12-08 00:19:51

问题


i have a big jpeg image that i want to load in tiles asynchronously in my opengl engine. Everything works well if its done on the main thread but its slow.

When i try to put the tile loading on an NSOperationBlock, it always crashes when trying to access the shared image data pointer that i previously loaded on the main thread.

There must be something i don't get with background operation because i assume i can access memory sections that i created on the main thread.

What i try to do is the following :

@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];

}

回答1:


I finally found out my problem...

I have read the Quartz2D doc and it seems that we should not use CGDataProviderCreateWithData and CGImageCreateWithJPEGDataProvider anymore. I guess there usage is not thread safe.

As suggested by the doc, i now use CGImageSource API like this :

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

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

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


来源:https://stackoverflow.com/questions/16672506/reading-cgimageref-in-a-background-thread-crashes-the-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!