2012-01-22 5 views
1

Я работаю над проектом iOS, который загружает UIImages из URL-адресов в фоновом потоке и отображает их в горизонтальном прокручиваемом прокрутке. Это поведение должно имитировать приложение собственной библиотеки фотографий для iPhone. У меня есть установка все, таким образом, что я считаю, должен работать, но на рисование UIImages в главном графическом UI контексте, я иногда вижу это сообщение печать в консоли:Загрузка 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:, который, как представляется, является исполнителем сообщения об ошибке в консоли. Однако при рисовании лежащего в основе CGImageRef изображения с использованием CGContextDrawImage все еще вызывает ту же ошибку. Полный исходный код можно найти в репозитории Github этого проекта в файле ANAsyncImageView.m.

EDIT: теперь я изменил фоновый поток, чтобы загрузить CGImage из файла, а затем обратный вызов в основной поток, передав CGImageRef с использованием бесплатного моста. К сожалению, это все равно создает ту же проблему, доказывая мне, что UIImage's 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

Смежные вопросы