我有一个 Collection View ,其中充满了来自服务器的大量数据:
细胞结构:
- 一张图片
- 每个单元格有 2 行文本
基本上,我的收藏布局是这样的——3 个单元格排成一排(多行),带有圆角和阴影。 我面临的问题是,当我从服务器收到 30 多个产品时,我的内存使用量增加到 200 MB,而在旧设备 (iOS 10.*) 上,我的 Collection View 屏幕滞后。
我接收数据的方式是:
- 在
Interactor
中,我请求产品的所有文本数据以及图像文件的链接, 在我的 Collection View
cellForItemAt
中,我显示了这些数据,然后我开始使用这个库加载图像 - Kingfisherif 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 上搜索了 allot 并阅读了很多关于优化的文章,但它们提供的大多是一般性建议,并没有反射(reflect)我在这里遇到的这种情况。 他们提供的是:
- 使用内存管理原则 - 完成
- 分页 - 没有
在测试时我发现,如果我用静态的剪辑图像填充 Collection View - 内存使用量会下降到 ±100 MB
我想问:
- 是否有针对 Collection View 的现成解决方案,这些解决方案已经过优化以处理大量图像数据?我搜索了github,但是大多数 Collection View 框架都与Cutom Layouts有关。
- 在处理大量数据时如何减少内存使用量?
- 图像的大小会导致这样的内存负载吗?
- 我能否避免使用分页,因为 Collection View 会重复使用单元格?
在此先感谢您的帮助,祝周末愉快!
最佳答案
- Kingfisher 已包含您需要的所有功能
- 您可以使用多级缓存,例如如果您达到内存使用限制,那么它将在磁盘上缓存数据
- 是的,如果你在内存中保存了很多图片
- 如果单元格结束显示在屏幕上,您可以禁用下载图像。
我认为你需要实现 UITableViewDelegate func 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 还会在收到内存警告通知时自动清除内存缓存。
关于ios - 具有大量数据 Swift 的 CollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52668177/