Загрузка UIImage в фоновом потоке вызывает ошибку ImageIO - PullRequest
1 голос
/ 22 января 2012

Я работаю над проектом iOS, который загружает UIImages из URL-адресов в фоновом потоке и отображает их в виде горизонтальной прокрутки.Такое поведение должно имитировать поведение приложения для библиотеки фотографий для iPhone.У меня все настроено так, что, я считаю, должно работать, но при отрисовке UIImages в основном графическом контексте пользовательского интерфейса я иногда вижу, как это сообщение распечатывается в консоли:

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 .

РЕДАКТИРОВАТЬ: я изменил фоновый поток, чтобы загрузить CGImage из файла, изатем обратный вызов в основной поток, передавая CGImageRef с использованием бесплатного моста.К сожалению, это все еще создает ту же проблему, доказывая мне, что UIImage 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);

1 Ответ

6 голосов
/ 22 января 2012

UIKit не является потокобезопасным классом. Поэтому не следует вызывать UIImage из фона.

Вместо того чтобы создавать UIImages, визуализируйте файлы изображений в CGImageRefs. Вы можете передать один из них обратно в основной поток и сгенерировать UIImage из этого (вы все равно выиграете, перенеся тяжелый подъем декомпрессии изображения на фон).

...