【问题标题】:Memory issues with UIImage Animation Image CachingUIImage 动画图像缓存的内存问题
【发布时间】:2015-04-29 08:23:54
【问题描述】:

我这几天一直在努力解决这个问题,只是无法深入了解它。基本上我有使用 UICollectionView 来显示动画 UIImages 的键盘扩展。当它运行并且我切换到另一个应用程序然后切换回键盘时,我得到了大约 10mb 的峰值。几次交换后,这显然会使应用程序崩溃。

我已经使用了各种工具,看起来当键盘重新加载时我会获得大量额外的 UIImage,它们“最终”会被清理掉,但这需要一段时间,而且累积效果最大值会超出内存。我认为这与 UIImage 缓存动画图像有关,因为我从大约 150 - 200 个 UIImage 开始,这与我在所有单元格中的总动画帧大致相关。这样每次重新加载都会翻倍。

我已经把它扔进了细胞prepareForReuse:

override func prepareForReuse() {
    if imageView?.isAnimating() == true {
        NSLog("Stop Animating")
        imageView?.stopAnimating()
    }
    imageView?.animationImages = nil
    contentView.subviews.map({$0.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 上,但没有区别。

我花了很长时间才找到这个问题,现在我找到了,我很难过。很高兴发布您认为有帮助的任何代码,很高兴被指出正确的方向。

谢谢。

【问题讨论】:

  • 在完成后释放您的资源。例如 imageView.image = nil
  • 是的,这是有道理的,但我打算什么时候这样做?

标签: swift animation keyboard uiimage uicollectionview


【解决方案1】:

因此,这是一个双管齐下的解决方案。首先我做了这些小辅助函数:

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

希望这可以帮助某人:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2016-03-25
    • 1970-01-01
    • 2012-01-28
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多