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 手动处理,但显然不能。

希望这对某人有所帮助:)