IOS 上的图像缓存

Posted

技术标签:

【中文标题】IOS 上的图像缓存【英文标题】:ImageCaching on IOS 【发布时间】:2014-03-20 16:21:45 【问题描述】:

我的应用程序的内存有些问题。我检查了 Instruments 以获得更多关于这个问题的线索,我发现我 79% 的内存都被这个占用了:

所以我在谷歌上搜索过,有人说这是图像缓存,它把我所有的图像都保存在内存中。也许它来自我的分配?

这是我如何称呼我的图像:

info = [InfoModel getInfo:[NSString stringWithFormat:@"%d", self.idEnigme]];

    myImage = [UIImage imageNamed:[NSString stringWithFormat:@"res/img/%@", [info objectForKey:@"path1"]]];
    myImageView = [[UIImageView alloc] initWithImage:myImage];

    myImageView.frame = CGRectMake(0, 200, [[UIScreen mainScreen] bounds].size.width, 400);

    [self.scrollView addSubview:myImageView];

Info 是一个类,我在其中解析 Json 文件,其中是我的图像路径。

感谢您的帮助,这让我发疯了。

【问题讨论】:

【参考方案1】:

当您调用imageNamed:时,ios 会自动缓存您的图像以供将来使用

正如在几个地方所讨论的,包括这里:Does UIImageView cache images?

如果你知道你只打算使用它创建一次,你可以绕过这个缓存

[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:nil]]

改为

【讨论】:

当我使用UIImage imageWithContentsOfFile: 而不是imageNamed 并且我的图像不再出现... 您必须将文件路径而不是文件名传递给它,我将编辑我的答案 它有效。我会测试我应用的每张图片,然后发布我的反馈。 这意味着您还有其他一般的内存问题。我建议您执行堆射击分析。请参阅raywenderlich.com/23037/how-to-use-instruments-in-xcode 并搜索堆镜头【参考方案2】:

我不会担心太多,当应用收到内存不足警告时,UIImage 缓存会被清除。这一切都是自动处理的,因此任何不再使用的图像都会从内存中清除。

因此,如果您的应用因内存不足而崩溃,则不太可能是因为操作系统正在缓存不再使用的图像。

您可以使用 initWithData 而不是 imageNamed 来处理自己的图像缓存,但我怀疑这个解决方案会帮助您。

【讨论】:

我已经用 imageWithContentsOfFile 尝试过这样的事情,但它并没有解决我的问题。你知道它是从哪里来的吗?【参考方案3】:

我很担心下面的屏幕。当我在分配模式下启动“仪器”时,我看到我的应用程序的每个图像都添加到“生活”中。我真的不明白这怎么可能......

【讨论】:

查看活体并从右上角打开右侧的仪器面板。查看调用堆栈,看看您是否正确地释放了图像【参考方案4】:

我找到了问题并解决了。我会解释你是什么问题,也许它可以帮助别人。

真正的问题是我的 UIImage 初始化。最初我在方法中分配了我的 UIImage,如下代码:

NSString* fileName = [NSString stringWithFormat:@"%@%@%@", name, number, ext];
            UIImage *myImageHeader = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:nil]];
            UIImageView *myImageViewHeader = [[UIImageView alloc] initWithImage:myImageHeader];

            myImageViewHeader.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 277);

            [self.scrollView addSubview:myImageViewHeader];

最后我决定通过一个属性在我的 .h 中创建一个 UIImageview 并在我的方法中设置它,如下所示:

#.h
@property (weak, nonatomic) IBOutlet UIImageView *headerImage;

#.m
[self.headerImage setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:nil inDirectory:nil]]];

通过这种方式,我节省了很多内存,但我仍然有泄漏。所以我决定在使用后删除我 UIImageView 中的图像:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void)
            self.headerImage.image = nil;
        );

现在,我的应用只使用 8mb 内存并正确管理内存。

感谢您的帮助!

【讨论】:

以上是关于IOS 上的图像缓存的主要内容,如果未能解决你的问题,请参考以下文章

图像无法在 iOS 上的 Safari 上加载

CollectionView [高分辨率] 图像上的 iOS 内存峰值

iOS SDWebImage - 如何正确处理不同设备上的视网膜图像?

iOS - 优化。缓存图像

iOS超全开源框架项目和学习资料汇总数据库缓存处理图像浏览摄像照相视频音频篇

iOS 中的永久图像缓存