UIImage 动画图像缓存的内存问题
Memory issues with UIImage Animation Image Caching
几天来我一直在苦苦思索这个问题,就是无法追根究底。基本上我有键盘扩展,它使用 UICollectionView 来显示动画 UIImage。当它是 运行 并且我切换到另一个应用程序然后切换回键盘时,我遇到了大约 10mb 的峰值。这显然会在几次交换后使应用程序崩溃。
我已经检查过乐器,当键盘重新加载时,我似乎得到了一堆额外的 UIImage,它们 'eventually' 被清理了,但这需要一段时间,累积效果最大会超出内存.我认为这与 UIImage 缓存动画图像有关,因为我从大约 150 - 200 个 UIImages 开始,这与我在所有单元格中拥有的总动画帧大致相关。这几乎每次重新加载都会翻倍。
我已将其放入单元格 prepareForReuse:
override func prepareForReuse() {
if imageView?.isAnimating() == true {
NSLog("Stop Animating")
imageView?.stopAnimating()
}
imageView?.animationImages = nil
contentView.subviews.map({[=10=].removeFromSuperview()})
imageRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
imageView = UIImageView(frame: imageRect!)
type = nil
super.prepareForReuse()
imageView?.contentMode = UIViewContentMode.ScaleAspectFit
contentView.addSubview(imageView!)
}
但无济于事。这甚至不会在重新加载时被调用。因此,正在创建新单元格,但可能没有正确清除旧单元格?
我试过运行这个:
func clearCellImages(){
for cell in collectionView.visibleCells(){
cell.imageView!?.animationImages = nil
cell.imageView!!.image = nil
}
}
关于 viewDidDisappear 和 deinit,但没有区别。
我花了很长时间才找到这个问题,现在我找到了,我很困惑。很高兴 post 任何您认为有帮助的代码,很高兴被指出正确的方向。
谢谢。
所以这是一个双管齐下的解决方案。首先,我制作了这些小辅助函数:
func clearCells(){
for cell in collectionView.visibleCells(){
clearCell(cell as! MyCellView)
}
}
func clearCell(cell:MyCellView){
if let iv = cell.imageView {
iv.animationImages = nil
iv.image = nil
iv.removeFromSuperview()
}
}
我在 viewWillDisappear
上调用了 clearCells
,发现 UIImages
和内存使用有所下降,但是,如果我滚动了,这很有可能,那么图像在当前不可见的单元格中使用的那些未被取消引用,导致了一个小的,但不是微不足道的内存蠕变。我通过在 didEndDisplayingCell
委托方法上调用 clearCell
来修复此问题:
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
clearCell(cell as! MyCellView)
}
我真的以为这种管理可以处理,如果不是由 ARC 自动处理,或者由 UICollectionView
处理,那么至少可以通过 prepareCellForReuse
手动处理,但显然不能。
希望这对某人有所帮助:)
几天来我一直在苦苦思索这个问题,就是无法追根究底。基本上我有键盘扩展,它使用 UICollectionView 来显示动画 UIImage。当它是 运行 并且我切换到另一个应用程序然后切换回键盘时,我遇到了大约 10mb 的峰值。这显然会在几次交换后使应用程序崩溃。
我已经检查过乐器,当键盘重新加载时,我似乎得到了一堆额外的 UIImage,它们 'eventually' 被清理了,但这需要一段时间,累积效果最大会超出内存.我认为这与 UIImage 缓存动画图像有关,因为我从大约 150 - 200 个 UIImages 开始,这与我在所有单元格中拥有的总动画帧大致相关。这几乎每次重新加载都会翻倍。
我已将其放入单元格 prepareForReuse:
override func prepareForReuse() {
if imageView?.isAnimating() == true {
NSLog("Stop Animating")
imageView?.stopAnimating()
}
imageView?.animationImages = nil
contentView.subviews.map({[=10=].removeFromSuperview()})
imageRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
imageView = UIImageView(frame: imageRect!)
type = nil
super.prepareForReuse()
imageView?.contentMode = UIViewContentMode.ScaleAspectFit
contentView.addSubview(imageView!)
}
但无济于事。这甚至不会在重新加载时被调用。因此,正在创建新单元格,但可能没有正确清除旧单元格?
我试过运行这个:
func clearCellImages(){
for cell in collectionView.visibleCells(){
cell.imageView!?.animationImages = nil
cell.imageView!!.image = nil
}
}
关于 viewDidDisappear 和 deinit,但没有区别。
我花了很长时间才找到这个问题,现在我找到了,我很困惑。很高兴 post 任何您认为有帮助的代码,很高兴被指出正确的方向。
谢谢。
所以这是一个双管齐下的解决方案。首先,我制作了这些小辅助函数:
func clearCells(){
for cell in collectionView.visibleCells(){
clearCell(cell as! MyCellView)
}
}
func clearCell(cell:MyCellView){
if let iv = cell.imageView {
iv.animationImages = nil
iv.image = nil
iv.removeFromSuperview()
}
}
我在 viewWillDisappear
上调用了 clearCells
,发现 UIImages
和内存使用有所下降,但是,如果我滚动了,这很有可能,那么图像在当前不可见的单元格中使用的那些未被取消引用,导致了一个小的,但不是微不足道的内存蠕变。我通过在 didEndDisplayingCell
委托方法上调用 clearCell
来修复此问题:
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
clearCell(cell as! MyCellView)
}
我真的以为这种管理可以处理,如果不是由 ARC 自动处理,或者由 UICollectionView
处理,那么至少可以通过 prepareCellForReuse
手动处理,但显然不能。
希望这对某人有所帮助:)