Асинхронная подготовка изображений в iOS

13 Дек
2011

Мне очень нравится работать над оптимизацией скорости работы приложения для iOS(Android), особенно те случаи, когда достаточно небольшого куска кода чтобы улучшить отзывчивость интерфейса в разы или десятки раз.
Итак, эта статья направлена на то, чтобы показать как использовать «Best practices» в ситуации, когда необходимо отобразить список элементов с картинками, лежащими на файловой системе.

Типичный вариант использования:
UITableView со списком элементов, каждый из которых содержит картинку, лежащую на файловой системе. В этом случае обычно используют метод [UIImage imageWithContentsOfFile:] для того, чтобы загрузить изображение в память, и потом присвоить его компоненту [UIImageView setImage:]. Вызов этих методов происходит при генерации элемента списка внутри метода tableView:cellForRowAtIndexPath. В большинстве случаев, это и является причиной дерганного (не плавного) пролистывания таблицы с элементами, так как чтение и декомпрессия изображения с файловой системы занимает большую часть времени.

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

Предлагаемое решение, на основе очередей и модного Grand Central Dispatch позволит максимально эффективно и просто решить проблему скроллинга. Исходные коды класса доступны на github.

Использовать очень просто: после добавления в проект классов, необходимо заменить вызов методов:

UIImage *image = [UIImage imageWithContentsOfFile:<imageFileName>];
[imageView setImage:image];

на

[imageLoader displayImage:<imageFileName> inImageView:imageView];


В результате чего, картинка будет загружена из файла, уменьшена до размера, необходимого компоненту imageView в соответствии с прописанным ContentMode, в отдельном потоке.

Предварительно необходимо инициализировать ImageLoader в методе init вашего ViewController’a:

imageLoader = [[ImageLoader alloc] init];


а также освободить в методе dealloc:

[imageLoader release]


Приятного использования.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх