2013-05-20 6 views
7

Я пытаюсь загрузить изображение из локального URL с помощью следующего:UIImage setImage очень, очень медленно

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:fileURL]]; 
[self.imageView setImage:image]; 
NSLog(@"imageView set"); 

Так что я вижу в консоли «ImageView набор» почти сразу, но это занимает очень долгое время для его отражения в пользовательском интерфейсе (иногда несколько минут!).

Любая идея, почему это происходит?

+0

Какова ценность 'fileURL'? Какой поток работает? – Tim

+0

Какое измерение, размер и формат файла вашего изображения? – Raptor

+0

ФайлURL является gif в каталоге документов. Размер файла изображения меньше 1-2 МБ. Функция запускается IBAction, но я предполагаю, что она запущена в основном потоке? –

ответ

-1

Загрузка изображения из NSData занимает больше времени. Вместо этого вы можете просто использовать следующий код:

UIImage *image = [UIImage imageWithContentsOfFile:fileURL]; 

Попробуйте.

+0

Ты серьезно, правда? O.o – holex

4

Вы должны загрузить инструменты и посмотреть, что именно он делает.

Для начала вы должны сделать все возможное, чтобы избежать ввода-вывода в нитке чертежа. Кроме того, существуют ли другие запросы ввода-вывода одновременно?

A UIImage необязательно должно быть уникальным представлением растрового изображения - оно может поддерживаться кешем и/или загружаться лениво. Поэтому просто потому, что «образ» задан, не означает, что оптимальная растровая карта была загружена в память и подготовлена ​​для рендеринга - она ​​может быть отложена до запроса рендеринга (рисования).

Профилирование OTOH скажет вам (как правило), почему он занимает больше времени, чем ожидалось.

+0

Спасибо. Я определенно должен это сделать. Единственное, что происходит на странице, - это воспроизведение видео с удаленного URL-адреса. –

+0

@ AndyHin хорошо, если этот тяжелый видеоматериал синхронно и выполняется в основном потоке, тогда он может заблокировать рисунок («заморозить» приложение), пока видео не будет готово. «Установка» изображения не отображает его сразу - он просто говорит, что «это представление нужно рисовать, рисовать его в следующем цикле рисования», - но большая часть работы или ввода-вывода в основном потоке могла блокировать выполнение перерисовки графика просмотра потому что поток - это чтение файлов, загрузка видео или ряд других вещей, которые препятствуют движению основного потока вперед. – justin

-2

Так что я попытался следующее:

dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:fileURL]]; 
    [self.imageView setImage:image]; 
    NSLog(@"imageView set"); 
}); 

И это совсем немного быстрее. Не знаю, почему.

+3

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

+2

Вы пытались использовать 'dispatch_get_main_queue' вместо этого? Вы говорите, что иногда требуется _minutes_ для загрузки локального изображения, что часто является признаком того, что вы случайно используете фоновый поток при использовании классов UIKit. – omz

+0

@omz спасибо. Я попытался использовать dispatch_get_main_queue вместо этого, и это действительно даже быстрее. Так что, похоже, это решило. Когда IBAction запускает функцию - это выполняется в потоке пользовательского интерфейса? –

10

Это случилось со мной, когда я устанавливал изображение в фоновом потоке (в котором я загружал файл изображения). Просто убедитесь, что ваш код запущен в основном потоке. Изображение сразу изменится.

// In a background thread... 

UIImage *image = ... // Build or download the image 

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.imageView setImage:image]; // Run in main thread (UI thread) 
}); 
Смежные вопросы