Какой идеальный способ загрузить / очистить данные в UICollectionView из Bundle.main?

#ios #swift #uicollectionview #gif #collectionview

#iOS #swift #uicollectionview #gif #collectionview

Вопрос:

У меня около 100 GIF-файлов в основном пакете. Я загружаю все во время viewDidLoad() в массив. Этот массив является источником данных для UICollectionView. Проблема в том, что эти GIF-файлы занимают много памяти, что вызывает медлительность и приводит к сбою приложения из-за нехватки памяти. Когда я начинаю прокрутку, отладчик памяти показывает более 800 МБ, а затем выходит из строя.

Сбой

Я рассматривал возможность интеграции сторонних библиотек для оптимизации производительности GIF-файлов. Затем я подумал о создании какого-то локального решения для кэширования, где я мог бы выгружать память и извлекать данные при необходимости в фоновом режиме, как только ячейка отключается от просмотра. Это правильный подход или я все усложняю?

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

1. Не загружайте все GIF-файлы. Просто загрузите те, которые действительно необходимы в cellForItem .

Ответ №1:

  1. Загружайте URL-адреса пакетов gif (только URL, не данные изображения) в viewDidLoad .
 override func viewDidLoad() {
    gifUrls = ...
}
  
  1. Используйте сторонний просмотр в ячейке просмотра коллекции для отображения gif. Например, мы используем BBWebImage.
 // In collection view cell
imageView = BBAnimatedImageView(frame: frame)
  
  1. В загружайте gif асинхронно в collectionView(_:cellForItemAt:) .
 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseID, for: indexPath)
    cell.tag = indexPath.item
    let url = gifUrls[indexPath.item]
    DispatchQueue.global().async {
        guard let data = try? Data(contentsOf: url) else { return }
        let gif = BBAnimatedImage(bb_data: data)
        DispatchQueue.main.async {
            guard cell.tag == indexPath.item else { return }
            cell.imageView.image = gif
        }
    }
}
  

Ответ №2:

Как сказал @rmaddy, вы могли бы загружать GIF-файлы в цикле видимых ячеек с помощью этих методов:

 func collectionView(_ collectionView: UICollectionView, 
             willDisplay cell: UICollectionViewCell, 
               forItemAt indexPath: IndexPath)
  

Подробнее

И:

 func collectionView(_ collectionView: UICollectionView, 
        didEndDisplaying cell: UICollectionViewCell, 
               forItemAt indexPath: IndexPath)
  

Подробнее

Загрузите gif willDisplay и выгрузите его didEndDisplaying .

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

1. В настоящее время я загружаю все GIF-файлы в массив в viewDidLoad. Как еще я должен загружать GIF-файлы из пакета?