В моем приложении iOS у меня есть UICollectionView
, который отображает около 1200 маленьких (35x35 точек) изображений. Изображения сохраняются в комплекте приложений.
Я правильно использую UICollectionViewCell
, но все еще имею проблемы с производительностью, которые меняются в зависимости от того, как я адресую загрузку изображений:
-
Мое приложение - это расширение приложения, а у них ограниченная память (в этом случае 40 МБ). Помещение всех 1200 изображений в каталог "Активы" и их загрузка с помощью
UIImage(named: "imageName")
привели к сбоям в работе системы - кэшированные изображения системы, которые заполнили память. В какой-то момент приложение должно выделять большие части памяти, но они недоступны из-за кэшированных изображений. Вместо запуска предупреждения о памяти и очистки кеша операционная система просто убила приложение. -
Я изменил подход, чтобы избежать кэширования изображений. Я помещал изображения в свой проект (а не в каталог asssets) в виде png файлов, и теперь я загружаю их с помощью
NSBundle.mainBundle().pathForResource("imageName", ofType: "png")
. Приложение больше не вылетает из-за ошибки памяти, но загрузка одного изображения занимает гораздо больше времени, и быстрая прокрутка отстает даже на новейших iPhone.
У меня есть полный контроль над изображениями и их можно преобразовать, например, в .jpeg или оптимизировать их (я уже пробовал ImageOptim и некоторые другие варианты без успеха).
Как я могу решить обе эти проблемы производительности сразу?
РЕДАКТИРОВАТЬ 1:
Я также попытался загрузить изображения в фоновый поток. Это код из моего подкласса UICollectionViewCell
:
private func loadImageNamed(name: String) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { [weak self] () in
let image = bundle.pathForResource(name, ofType: "png")?.CGImage
if name == self?.displayedImageName {
dispatch_async(dispatch_get_main_queue(), {
if name == self?.displayedImageName {
self?.contentView.layer.contents = image
}
})
}
})
}
Это делает прокрутку гладкой, не потребляя дополнительной памяти для кэширования , но при прокрутке в определенное место программно (например, когда UICollectionView
прокручивается вверх) вызывает другую проблему: Во время анимации прокрутки изображения не обновляются (прокрутка выполняется слишком быстро для их загрузки), и после прокрутки завершается, отображаются неправильные изображения для доли секунды - и один за другим заменяются правильными. Это очень тревожно визуально.
ИЗМЕНИТЬ 2:
Я не могу группировать небольшие изображения в более крупные изображения и отображать те, которые были предложены этим ответом.
Причины:
- Рассмотрим различные размеры и ориентации экрана. Для каждого из них должны быть предустановленные изображения, которые сделают приложение загруженным огромным.
- Маленькие изображения могут отображаться в другом порядке, некоторые из них могут быть скрыты в некоторой ситуации. Я, судя по всему, не могу предустановленных изображений для каждой возможной комбинации и заказов.