2013-05-21 3 views
2

У меня есть большое jpeg-изображение, которое я хочу загружать в плит асинхронно в моем движке opengl. Все работает хорошо, если это делается на основной нити, но медленнее.Чтение 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

Совет: обновление пользовательского интерфейса должно быть сделано в основном цикле выполнения. Вы можете выполнять обработку в фоновом потоке, но принудительно в основном цикле запуска при фактическом обновлении пользовательского интерфейса. –

+0

Да, я действительно абстрагировал эту часть кода в моем примере, thx – AkademiksQc

+0

Является одним из ваших refs NULL? – CodaFi

ответ

2

я наконец-то нашел мою проблему ...

Я прочитал документ Quartz2D и, кажется, что мы не должны использовать 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