【问题标题】:How do I release cached images when using UIImage(data:)?使用 UIImage(data:) 时如何释放缓存的图像?
【发布时间】:2020-12-03 14:38:51
【问题描述】:

我注意到收藏视图中的图像缓存占用了大量内存,需要了解如何释放它。我了解UIImage(named:)UIImage(contentsOfFile:) 之间的区别。但是,我使用的是UIImage(data:),我似乎找不到任何关于在这种情况下释放图像缓存的文档。任何帮助表示赞赏。这是我的代码 sn-p:

if let setImage = cell?.viewWithTag(101) as? UIImageView {
    if let url = URL(string: imageURLs[indexPath.item]) {
        let task = URLSession.shared.dataTask(with: url, completionHandler: { data, _, error in
            guard let data = data, error == nil else {
                print("No data detected: \(Error.self)")
                return
            }
            DispatchQueue.main.async {
                let newImageData = UIImage(data: data)

                self.imageData[indexPath.item] = newImageData!
                setImage.image = self.imageData[indexPath.item] as? UIImage
            }
        })
        task.resume()
        URLSession.shared.finishTasksAndInvalidate()
    }
}

【问题讨论】:

  • 您能告诉我们您是如何创建单元格的吗?你在使用dequeueResusableCell 方法吗?
  • 顺便说一句,在共享会话上调用finishTasksAndInvalidate 是没有意义的。正如the docs 所说,“在shared 方法返回的会话上调用此方法无效。”。
  • @TheAppMentor 是的。我正在使用 dequeueReusableCell 方法。我也在我的单元格上使用 prepareForReuse 方法。
  • @Rob 明白了。我把它留在那里是因为我只是想尝试一下,看看会发生什么。这对我正在处理的问题是多余的。

标签: ios swift memory-management uiimage image-caching


【解决方案1】:

UIImage(data:) 不存储在系统映像缓存中。因此,如果您从 imageData 中删除对相关图像的所有引用,确保图像视图正在释放等,您应该会很好。

如果imageData 是一个简单的集合,请考虑将其设为NSCache,您可以在其中限制总计数或成本。此外,我们经常采用两层缓存机制(内存限制更小,持久存储缓存更大)。

您可能会考虑使用众多第三方库之一(AlamofireImage、KingFisher、SDWebImage 等),因为它们倾向于采用不错的缓存策略,让您摆脱困境。它们也都为UIImageView 提供了不错的“异步图像”扩展。 (例如,如果您在大型集合视图中快速滚动,您与我们共享的实现将遭受积压问题,这些UIImageView 扩展很容易解决。)您的UICollectionViewDataSource 真的不应该背负着这种代码。

【讨论】:

  • 您能给我举个例子,说明如何释放与我的 imageData 关联的引用吗?我正在研究使用 NSCache 或您提到的任何库。看看是否有帮助。缓存是否是问题只是我的一个有根据的猜测。基本上,发生的事情是每当重新加载collectionview时,内存影响就会不断增加并且永远不会下降。当我注释掉我共享的代码时,问题就消失了。
  • 如果它是可选的,请将其设置为nil。或致电removeAll。如果是字典,请将其设置为[:]。如果是数组,则设置为[]。你的表现不足以回答这个问题......
  • 我应该在代码中分享哪些细节可以帮助解决这个问题?
  • imageData的声明。是字典吗?您真的在问如何从字典中删除单个项目吗?您是在问如何从字典中删除所有内容?
  • 这是一个数组。每当我离开 viewController 时,我已经尝试通过将数组设置为 [] 并将图像设置为 nil 来释放引用。但是,只要我返回加载集合视图的视图控制器,内存使用量就会继续上升。这告诉我有一些东西留在记忆中,与我无法确定的代码 sn-p 有关。
【解决方案2】:

我的印象是 Firestore 自动缓存适用于云存储,但它仅适用于云数据库。一旦我用 NSCache 实现了本地缓存,我的问题就解决了。

【讨论】:

  • @Rob 感谢您帮助我在考虑本地缓存和释放引用方面走上了正确的道路。
猜你喜欢
  • 1970-01-01
  • 2012-06-10
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 2012-01-28
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多