Сообщение от отладчика: прекращено из-за проблемы с памятью При прокрутке в UITableView / UICollectionView с изображениями GIF Библиотека Kingfisher - PullRequest
0 голосов
/ 01 марта 2019

Фрагмент кода

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: BroadCastFeedTableViewCell = broadCastTableView.dequeueReusableCell(withIdentifier: "broadCastFeedCell") as BroadCastFeedTableViewCell

    cell.singlePicImageView.kf.setImage(with: URL(string: (self.broadCastArray[indexPath.row].images_url?[0])!), placeholder: nil, options: nil, progressBlock: nil) 
            { (theImage, error, cache, url) in
                if theImage != nil{
                    let imageHeight = self.getAspectRatioOfDownloadedImages(resolution: self.broadCastArray[indexPath.row].image_resolution![0])
                    cell.collectionContentViewHeightConstraint.constant = imageHeight

                    cell.layoutSubviews()
                    cell.layoutIfNeeded()

                }else {
                    let placeHolderCenterCordi = UIView().getViewRelationWithSuperSuperView(viewControllerView: cell.collectionContentView, 
                                                                    subView: cell.singlePicImageView, subObjFrame: cell.singlePicImageView.frame)

                    cell.singlePicImageView.addPlaceHolderImageView(cordinates: placeHolderCenterCordi.center)
                }
               self.broadCastTableView.rowHeight = UITableViewAutomaticDimension
            }
}

В приведенном выше коде я использовал библиотеку Kingfisher для загрузки изображения с удаленного сервера, когда следующий код загружает определенные изображения (GIF, JPEG, PNG), которые могутимеют большой размер (около 2-5 МБ), приложение закрывается из-за проблем с памятью.В iPhone 5s он завершается сразу же после запуска приложения, а в других моделях iPhone (7, 6) - после прокрутки в течение определенного промежутка времени.Я также проверил Распределение и утечку, но я не понял / нашел много о проблеме.

Я также приложил График профилирования

Следующее изображение показывает, что у них нет таких утечек памяти, но из-за какой-то проблемы приложение прекращает работу

Пожалуйста,помогите мне решить вышеуказанную проблему.

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

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

  1. Посмотрите на UITableViewDataSourcePrefetching.Это способ загрузить изображения до того, как они будут отображены в ячейке.
  2. Узнайте, как создать вспомогательную функцию где-то, которая начинает загрузку и позволяет отменить загрузку.Например, когда вы быстро прокручиваете таблицу вниз, каждая ячейка начинает загрузку изображения, даже если оно не было показано.Вы можете отменить загрузку, если ячейка пропала.
  3. Ячейки должны быть в основном элементом интерфейса вашего кода.Идея состоит в том, чтобы попытаться извлечь сетевые запросы из самой ячейки и убедиться, что в ячейке содержатся только элементы (изображения, метки, представления) для визуализации, в ячейке есть функция func configure (withModel: Model), и чтов cellForRow вы просто передаете данные для рендеринга.Ячейки используются повторно и часто обновляются, вам не следует выполнять на них кучу вещей.Помните, что когда ячейка загружается, она будет вызывать эти функции, затем она может исчезнуть с экрана и снова вернуться, и она снова и снова выполнит все это.
  4. У вас есть выполнение класса ячейки?правильная компоновка обновляется и обновляется, и старайтесь не делать этого в cellForRow.Все, что вы могли бы сделать, это просто убедиться, что просмотр изображений получает изображение, но не полагаться на выполнение изменений ячейки, и эта загрузка изображения является асинхронной, и эта ячейка может даже не быть там, когда загрузка заканчивается.
  5. Кэширование.Можете ли вы кэшировать эти изображения или они постоянно меняются?убедитесь, что вы понимаете, как KF кеширует ваши изображения и как вам нужно.Если нет, адаптируйтесь.
  6. [придирки] вы звоните cell.layoutSubviews(), а затем cell.layoutIfNeeded().Первый - принудительный вызов layoutSubviews, второй - проверка наличия элементов, которые необходимо выложить перед вызовом layoutSubView.Если вы хотите пометить вид для разметки, вы можете сделать setNeedsLayout ().это сделает обновления макета представления в следующем цикле.
0 голосов
/ 04 марта 2019

Отвечая на мой собственный вопрос

Следующее сработало для меня

Я использовал класс AnimatedImageView для своего UIImageView, предоставленного библиотекой kingfisher

let imageView = AnimatedImageView()
imageView.kf.setImage(with: URL(string: "your_image"), placeholder: nil, options: [.targetCache(ImageCache(name: "your_cache_name")), .backgroundDecode], progressBlock: nil) { (image, error, cache, url) in 
  // some code
}

Примечание Важно

[. TargetCache (ImageCache (name: "your_cache_name")), .backgroundDecode]

В приведенном выше коде для опции атрибут, который я использовалмой собственный кэш (ImageCache (имя: "your_cache_name")) и попросил зимородка декодировать изображение в фоновом режиме

0 голосов
/ 01 марта 2019

Я думаю, что в вашем коде вы используете «Self» в качестве сильных рефренов, поэтому он создает сильный референсный цикл, из-за этого возникает утечка памяти.так что в этот момент вы можете попробовать с [слабым я], а затем запустить свой код

cell.singlePicImageView.kf.setImage(with: URL(string: (self.broadCastArray[indexPath.row].images_url?[0])!), placeholder: nil, options: nil, progressBlock: nil) 
        { [weak self] (theImage, error, cache, url) in
            if theImage != nil{
                let imageHeight = self?.getAspectRatioOfDownloadedImages(resolution: self?.broadCastArray[indexPath.row].image_resolution![0])
                cell.collectionContentViewHeightConstraint.constant = imageHeight

                cell.layoutSubviews()
                cell.layoutIfNeeded()

            }else {
                let placeHolderCenterCordi = UIView().getViewRelationWithSuperSuperView(viewControllerView: cell.collectionContentView, 
                                                                subView: cell.singlePicImageView, subObjFrame: cell.singlePicImageView.frame)

                cell.singlePicImageView.addPlaceHolderImageView(cordinates: placeHolderCenterCordi.center)
            }
           self?.broadCastTableView.rowHeight = UITableViewAutomaticDimension
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...