gpt4 book ai didi

ios - 更新 UIImageView 占用太多内存

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:07:58 25 4
gpt4 key购买 nike

我有一个大约每 20 毫秒执行一次的代码块(它是 Core Audio 音频单元的渲染回调方法);这种方法运行一些计算并更新 UIImageView 的图像。为了强制刷新UI,我在主线程中调度了UIImageView的图片的setter,如下:

[audioUnit setOutputBlock:^() {
// ...
// some heavy calculations
// ...
dispatch_sync(dispatch_get_main_queue(), ^{
imageView.image = images[index];
});
}];

如果没有图像的 setter ,应用程序占用大约 50mb 的内存,而图像的刷新会使它跳到大约 300mb,导致内存警告并在 iPhone < 5 上崩溃。

面对此类问题的最佳方法应该是什么?

非常感谢,丹

最佳答案

您的数据集在这里相当大。图片解压后想想:1136高x 640宽x每像素4字节x 110张图片=320MB。不幸的是,图像解压缩不是快速/免费的,所以如果你想让它发生在 50Hz,你将不得不玩一些技巧。对于初学者,您可能无法同时将所有 110 张图像保存在内存中,所以不要尝试这样做。

另外,不要使用 -[UIImage imageNamed:]。它以您无法控制的方式积极缓存图像的解压缩版本。我会使用 [[UIImage alloc] initWithContentsOfFile:] 以便最大程度地控制图像的生命周期。

如果解压缩时间可以忍受,那么它可能很简单,只需保留一组图像路径,然后在最后一分钟制作您需要的一个 UIImage 对象。不过,我怀疑 20 毫秒对于每次解压来说有点太慢了。

另一种选择是预解压缩图像,然后将解压缩的数据写入磁盘上应用程序的缓存目录。这样,您仍然从磁盘加载,但它是直接读取,而不是每次都读取和解压缩。请注意,这必然会消耗 ~320MB 的磁盘存储空间。不是可怕。

为了更进一步,通过一些额外的恶作剧,您可能能够得到它,以便图像在磁盘上,然后您的应用程序中的图像对象可以指向对应于每个文件的 mmap 内存区域在磁盘上。通过这种方式,您可以让虚拟内存系统决定内存中重要的内容和不重要的内容,并且您可以“免费”获得这些信息。这似乎是最好的选择。 (编辑:我看了看,UIImage 似乎已经在幕后映射图像,所以这个建议可能对你帮助不大。)

我从您发布的代码片段中注意到一件事:您在 block 闭包中捕获了整个数组,这意味着数组中的每个图像在该 block 的持续时间内都保持事件状态(以及更长的一段时间,直到libdispatch 决定释放该 block 。)它可能不足以避免这种情况(因此我在上面提出了建议),但它肯定无助于捕获整个数组。这就是我的意思:

[audioUnit setOutputBlock:^() {
@autoreleasepool {

NSArray* images = [NSArray array]; // or whatever
// ...
// some heavy calculations
// ...
UIImage* theOneImageWeNeed = images[index];
}
dispatch_sync(dispatch_get_main_queue(), ^{
imageView.image = theOneImageWeNeed;
});
}];

这将使您需要的一个图像保持事件状态,并更积极地释放计算生成的任何其他对象。

关于ios - 更新 UIImageView 占用太多内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19561285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com