CGImage/UIImage, лениво загружающиеся на UI, распараллеливают задержку причин

Моя программа отображает поверхность горизонтальной прокрутки, размещенную рядом с UIImageViews слева направо. Код работает на потоке UI, чтобы гарантировать, чтобы недавно видимые UIImageViews имели недавно загруженный UIImage, присвоенный им. Загрузка происходит на фоновом потоке.

Все работает почти прекрасное, кроме существует задержка, поскольку каждое изображение становится видимым. Сначала я думал, что мой второстепенный рабочий блокировал что-то в потоке UI. Я провел много времени, смотря на него и в конечном счете понял, что UIImage делает некоторую дополнительную ленивую обработку на потоке UI, когда это сначала становится видимым. Это озадачивает меня, так как мой рабочий поток имеет явный код для распаковки данных JPEG.

Так или иначе на догадке я написал некоторый код для рендеринга во временном графическом контексте на фоновом потоке и - конечно же, задержка ушла. UIImage теперь предварительно загружается на моем рабочем потоке.Пока все хорошо.

Проблема - то, что моя новая "сила ленивая загрузка изображения" метод ненадежна. Это вызывает неустойчивый EXC_BAD_ACCESS. Я понятия не имею, что UIImage на самом деле делает негласно. Возможно, это распаковывает данные JPEG. Так или иначе метод:

+ (void)forceLazyLoadOfImage: (UIImage*)image
{
 CGImageRef imgRef = image.CGImage;

 CGFloat currentWidth = CGImageGetWidth(imgRef);
 CGFloat currentHeight = CGImageGetHeight(imgRef);

    CGRect bounds = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);

 CGAffineTransform transform = CGAffineTransformIdentity;
 CGFloat scaleRatioX = bounds.size.width / currentWidth;
 CGFloat scaleRatioY = bounds.size.height / currentHeight;

 UIGraphicsBeginImageContext(bounds.size);

 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextScaleCTM(context, scaleRatioX, -scaleRatioY);
 CGContextTranslateCTM(context, 0, -currentHeight);
 CGContextConcatCTM(context, transform);
 CGContextDrawImage(context, CGRectMake(0, 0, currentWidth, currentHeight), imgRef);

 UIGraphicsEndImageContext();
}

И EXC_BAD_ACCESS происходит на строке CGContextDrawImage. ВОПРОС 1: мне разрешают сделать это на потоке кроме потока UI? ВОПРОС 2: Что на самом деле "предварительно загружает" UIImage? ВОПРОС 3: Что официальный путь состоит в том, чтобы решить эту проблему?

Спасибо за чтение всего этого значительно ценился бы любой совет!

12
задан skaffman 29 July 2010 в 07:07
поделиться

1 ответ

Методы UIGraphics* предназначены для вызова только из главного потока. Вероятно, они являются источником вашей проблемы.

Вы можете заменить UIGraphicsBeginImageContext() вызовом CGBitmapContextCreate(); это немного сложнее (нужно создать цветовое пространство, вычислить буфер нужного размера для создания и выделить его самостоятельно). Методы CG* прекрасно работают из другого потока.


Я не уверен, как вы инициализируете UIImage, но если вы делаете это с помощью imageNamed: или initWithFile:, то, возможно, вы сможете заставить его загрузиться, загрузив данные самостоятельно, а затем вызвать initWithData:. Вероятно, заикание вызвано ленивым вводом/выводом из файла, поэтому инициализация его объектом данных не даст ему возможности читать из файла.

.
7
ответ дан 2 December 2019 в 03:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: