Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios swift-UICollectionView或UIImage-如何防止图像缓存_Ios_Swift_Memory Leaks_Uiimage_Uicollectionview - Fatal编程技术网

Ios swift-UICollectionView或UIImage-如何防止图像缓存

Ios swift-UICollectionView或UIImage-如何防止图像缓存,ios,swift,memory-leaks,uiimage,uicollectionview,Ios,Swift,Memory Leaks,Uiimage,Uicollectionview,我有一个UICollectionView,有4个单元格,呈网格模式,没有滚动。每个单元格都有一个imageView。图像存储在资产文件夹中,并通过名称引用检索(见下文)。在一些UI操作之后,想法是 collectionView.reloadData() 并替换每个单元格中的图像 一切正常,但每次重新加载后,内存使用量不断增加。我曾假设reloadData()转储不必要的数据,但这种经历让我感到困惑。发生了什么事 如果有帮助的话,我在某个地方读到了加载图像的内容 UIImage(name: .

我有一个
UICollectionView
,有4个
单元格
,呈网格模式,没有
滚动
。每个单元格都有一个
imageView
图像
存储在资产文件夹中,并通过名称引用检索(见下文)。在一些
UI
操作之后,想法是

collectionView.reloadData() 
并替换每个
单元格中的
图像

一切正常,但每次重新加载后,内存使用量不断增加。我曾假设
reloadData()
转储
不必要的
数据
,但这种经历让我感到困惑。发生了什么事

如果有帮助的话,我在某个地方读到了加载图像的内容

UIImage(name: ...) 
缓存图像。我曾试图证实这一点,但还是一无所获

我的代码非常简单,所以我想知道这是否是一些用于滚动的内存错误/功能(我不想要)


再一次,我希望停止记忆囤积。有什么想法吗?

你做得很正确,如果你使用的是
dequeueReusableCellWithReuseIdentifier(identifier:,forIndexPath:)
方法来实现单元格的可重用性,那么它肯定会处理单元格的可重用性

您没有其他方法从包中加载图像


内存中的一些细微变化可能会反映出来,但在子类UICollectionViewCell的
prepareforeuse
方法中,它可以继续执行

func prepareForReuse()
{
    super.prepareForReuse();
    cell.imageView.image = nil;
}

我从来没有机会了解图像缓存何时被逐出。
集合视图单元将退出队列并重新使用。这意味着,与将单元格移出屏幕后立即放入回收站相比,如果再次需要该单元格,则将其从该回收站中取出并放入视图层次结构(我想这称为flyweight模式),基本上可以节省实例化成本。
因此,当您处理图像时,图像不是存储在内存中的其他位置,而是存储在图像视图中,每次显示单元格并将新图像传递到图像视图时,都应释放旧图像。
如果将对旧映像的引用存储在其他位置(例如缓存或数组),则不会发生这种情况。
要从xcasset加载图像,只能使用
UIImage(名称:…)
,这意味着图像将被缓存。即使苹果公司表示,在内存紧张的情况下,该缓存将被逐出,并且从未见过这种情况“及时”发生,以避免应用程序崩溃。
您可以做的是不保存在xcasset文件夹中,而是保存在项目中的任何位置,通过这种方式,图像将加载到主捆绑包中,您可以使用以下常用方法从此处加载图像:

let path = NSBundle.mainBundle().pathForResource(<#T##name: String?##String?#>, ofType: <#T##String?#>)
    let image = UIImage(contentsOfFile: path!)
let path=NSBundle.mainBundle().pathForResource(,类型:)
让image=UIImage(contentsOfFile:path!)
请注意,路径是可选的。

作为一般规则,始终尝试使用相同视图大小的图像(以像素为单位)来节省资源,图像占用的空间意味着什么,只是它的压缩程度,当加载到内存中时,需要
n\u像素\u高度*n\u像素\u宽度*n\u通道
字节

您的图像是捆绑存储还是从服务器下载???@amitsigh-图像保存在资产文件夹中。是的,这就是原因,Assets文件夹do work with cachingit在我看来并不合适,每次我重新加载时,内存使用都会增加4MB。我现在运行它,看看它什么时候崩溃。内存使用似乎在650MB时达到峰值,可能是在所有图像都循环通过之后。考虑到每个图像只有200kB左右,而且大约有300个这样的图像,这看起来还是太过分了。不幸的是,这对我来说不起作用。不管怎样,谢谢。刚刚看到这个,想到了评论。@Proton所说的可能不是一个坏主意,尽管他可能指的是cellForItemAtIndexPath或cellForRowAtIndexPath。他想告诉您的是,在异步加载图像视图之前,尝试将其设置为空。tldr:就像制作一个“空图像”作为占位符一样,谢谢你的回答。我不知道如何将我的图片保存到其他地方,但这似乎是一个非常好的答案。与此同时,我想我会继续使用缓存。只是更新,我在应用程序运行时跟踪了内存缓存,一旦收到内存警告,缓存就会被转储。再次感谢你的解释。