【问题标题】:CoreGraphics memory warnings and crash; Instruments show no memory leakCoreGraphics 内存警告和崩溃;仪器显示没有内存泄漏
【发布时间】:2025-11-25 00:50:02
【问题描述】:

UPDATE 这段代码其实不是问题所在;注释掉所有 CoreGraphics 行并返回数组中的第一个图像作为结果并不能防止崩溃的发生,所以我必须往上游看。

我在 75 毫秒的 NSTimer 上运行它。它可以完美地处理 480x360 图像,并且可以运行一整天而不会崩溃。

但是当我向它发送 1024x768 的图像时,它会在大约 20 秒后崩溃,并给出几个内存不足的警告。

在这两种情况下,Instruments 都显示出绝对正常的内存使用情况:一个扁平的分配图,少于 1 兆字节的活动字节,始终没有泄漏。

那么,发生了什么? Core Graphics 是否以某种方式使用了过多的内存而不显示它?

另外值得一提的是:(NSMutableArray*)imgs 中的图像并不多——通常是三个,有时是两个或四个。无论如何都会崩溃。只有两个时,崩溃的速度会稍微慢一些。

- (UIImage*) imagefromImages:(NSMutableArray*)imgs andFilterName:(NSString*)filterName {

    UIImage *tmpResultant = [imgs objectAtIndex:0];

    CGSize s = [tmpResultant size];

    UIGraphicsBeginImageContext(s);

    [tmpResultant drawInRect:CGRectMake(0, 0, s.width, s.height) blendMode:kCGBlendModeNormal alpha:1.0];

    for (int i=1; i<[imgs count]; i++) { [[imgs objectAtIndex:i] drawInRect:CGRectMake(0, 0, s.width, s.height) blendMode:kCGBlendModeMultiply alpha:1.0]; }

    tmpResultant =  UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return tmpResultant;
}

【问题讨论】:

  • 崩溃日志显示多少内存?你在用[UIImage imageNamed:]吗?
  • 我没有在任何地方使用 [UIImage imageNamed:] -- 所有图像都是从相机捕获并发送到返回 NSMutableArrays 图像的 imageBuffer 类。它在没有崩溃日志输出的情况下崩溃,但在设备日志中看起来该进程正在使用 62582 rpages。

标签: iphone memory-management memory-leaks uiimage core-graphics


【解决方案1】:

在我看来,问题出在您显示的代码之外。显示在屏幕上的图像在应用程序内存之外有一个后备存储,即 width*height*bytes_per_pixel。如果您有太多后备存储,您还会收到内存警告和应用终止。

您可能需要在此处进行优化,以创建这些图像的较小优化版本以供显示或允许发布后备存储。还可以为某些不变的图层打开光栅化,以及将图层内容直接设置为 CGImage,而不是使用 UIImage。

您应该创建一个示例项目来演示没有其他代码围绕它的问题,并查看您是否仍然耗尽内存。但我怀疑您会发现,仅使用您展示的代码,您将无法重现该问题,因为它位于其他地方。

【讨论】:

  • 这完全正确;我减少了正在存储的UIImages 的数量,这阻止了崩溃。为了解决由此产生的限制,我将尝试将图像存储为UIImageJPEGRepresentations,然后根据需要将它们重新设置为[UIImage imageWithData:]。希望它会足够快。