具有大量数据的CollectionView Swift

时间:2018-10-05 14:45:56

标签: ios swift memory-management memory-leaks uicollectionview

我有一个收集视图,其中充满了来自服务器的大量数据:

单元格的结构:

  • 一张图片
  • 每个单元格中有两行文字

基本上,我的集合布局就像-一行(多行)中的3个单元带有圆角和阴影。 我面临的问题是,当我从服务器收到30多种产品时,我的内存使用量最多增加了200 MB,而在较旧的设备(iOS 10. *)上,我的屏幕显示了滞后的视图。

我接收数据的方式是:

  • Interactor中,我请求产品的所有文本数据以及图像文件的链接,
  • 在我的收藏夹视图cellForItemAt中显示此数据,然后开始使用该库-Kingfisher

    加载图像
    if url != nil {
        productsCell.productImage.kf.indicatorType = .activity
        productsCell.productImage.kf.setImage(with: url)
    } else {
        productsCell.productImage.image = clipImage
    }
    
  • 我收到的图像大小在4-6 Mb之间。

我将VIPER用作我的应用程序的体系结构,并检查了内存泄漏,但一切似乎都很好。当我在其他屏幕上启动应用程序时,我的内存使用量约为30 MB。因此,我面临的主要问题是加载图像数据。 我已经用Google搜索了配额,并阅读了许多有关优化的文章,但是它们大多提供了一般性建议,并且没有像我在这里反映的那样。 他们提供的是:

  • 使用内存管理原理-完成
  • 分页-否

在测试过程中,我发现,如果我用静态剪辑图像填充集合视图,则内存使用量将下降至±100 MB

我想问:

  • 是否存在针对收集视图的现成解决方案,这些解决方案已经过优化以处理大量图像数据?我已经搜索了github,但是大多数集合视图框架都与Cutom Layouts相关。
  • 在处理大量数据时如何减少内存使用量?
  • 图像大小会导致这种内存负载吗?
  • 我可以避免使用分页,因为集合视图重用了单元格吗?

提前感谢您的帮助,祝您周末愉快!

2 个答案:

答案 0 :(得分:1)

  • Kingfisher已经包含您需要的所有功能
  • 您可以使用多个级别的缓存,例如如果达到内存使用限制,那么它将在磁盘上缓存数据
  • 是的,如果您将许多图像保存在内存中
  • 如果单元格确实没有显示在屏幕上,则可以禁用下载图像。

我认为您需要实现UITableViewDelegate函数tableView:didEndDisplayingCell:forRowAtIndexPath

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.imageView.kf.cancelDownloadTask()
}

Kingfisher允许配置图像缓存参数(ImageCache),例如:

maxCachePeriodInSecond,maxMemoryCost,maxDiskCacheSize

因此,您可以配置maxMemoryCost,以使内存不超过50mb。

Kingfisher还会在收到内存警告通知时自动清除内存缓存。

答案 1 :(得分:0)

您的问题很可能是图像的尺寸很大,请尝试将其压缩为JPEG格式。您可以尝试压缩质量来找到一个最佳位置。

guard let imageRep = UIImageJPEGRepresentation(image, 0.3) else { return }