我几天来一直在反对这个问题,而且无法深究这一点。基本上我有键盘扩展,它使用UICollectionView来显示动画UIImages。当它正在运行并且我切换到另一个应用程序然后切换回键盘我得到一个大约10mb的尖峰。这显然会在几次交换后崩溃应用程序。
我已经通过乐器了,看起来我在键盘重新加载时会得到大量的额外UIImages,它们最终会被清理干净,但需要一段时间才会累积效果最大化记忆。我认为这与UIImage缓存动画图像有关,因为我开始使用大约150 - 200个UIImages,这大致与我在所有单元格中的动画帧总数相关。这样每次重新加载都会翻倍。
我把它扔进了细胞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上,但没有区别。
我花了很长时间才找到这个问题,现在我已经有了,我很难过。很高兴发布您认为有帮助的任何代码,非常乐意指出正确的方向。
感谢。
答案 0 :(得分:2)
所以这被证明是一个双管齐下的解决方案。首先,我做了这些小助手功能:
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()
}
}
我在clearCells
上调用了viewWillDisappear
,看到了UIImages
和内存使用的下降,但是,如果我滚动了,这很可能,那么有的图像用于目前不可见的细胞中没有被解除引用,导致一个小的,但不是无关紧要的记忆蠕变。我通过在clearCell
委托方法上调用didEndDisplayingCell
来解决此问题:
func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
clearCell(cell as! MyCellView)
}
我真的会想到这种管理可以处理,如果不是由ARC自动处理,或由UICollectionView
处理,那么至少可以通过prepareCellForReuse
手动处理,但显然不是。
希望这有助于某人:)