【问题标题】:Memory leak drawInRect on iOS5.0.1iOS5.0.1 上的内存泄漏 drawInRect
【发布时间】:2012-01-04 10:17:57
【问题描述】:

我有以下用于缩放图像的代码片段。这是在一个循环中,为每次传递创建和排出一个自动释放池。此代码在 iOS5.0 的模拟器、iPad 上的 iOS4.3 或模拟器中运行良好,但在 iPad1 上的 iOS5.0.1 上,经过 50-60 次后,drawInRect 开始消耗永远不会释放的内存。我一直在从辅助线程调用它,但现在在主线程上调用缩放操作。

UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

是我做错了什么还是 iOS5.0.1 的错误?

更新: 我已经尝试了很多测试。我已经能够证明用 XCode 4.0 编译的完全相同的代码在同一台 iPad 上运行良好。使用 XCode 4.2.1 编译的相同代码会导致内存不足。 此缩放例程正在后台线程中调用。我使用较低级别的核心图形调用编写了一个不同的缩放例程。 XCode 4.0 不会泄漏,但在我的 XCode 4.2.1 应用程序中会泄漏。在独立项目中运行的完全相同的例程和调用树似乎不会在 XCode 4.2.1 上泄漏(大量)内存。 我正在等待 Apple 关于这个的消息。同时我需要使用 XCode 4。我拥有的唯一安装映像需要 Snow Leopard,这意味着我使用的是我的 5.5 年旧机器。 谢谢

2012 年 1 月更新 这似乎仅在应用程序从 XCode 中启动时才会发生。在 iPad 上启动的相同可执行文件没有泄漏。具有相同例程的不同应用不会出现泄漏。

我已向 Apple 打开了一份错误报告,并向他们发送了一个重现该问题的项目。我预计它不会很快得到解决,但它似乎并不像我最初想象的那样普遍。

2012 年 6 月更新 尽管已向 Apple 发送了一个重现该问题的最小项目,但他们声称无法重现该问题并且没有取得任何进展。

【问题讨论】:

  • 显然我提出了一些棘手的问题,但几乎没有真正解决问题的答案。比如这个。在 XCode 4.2 中编译库可能真的是一个错误。使用适用于 iOS 4.2 的 SDK 编译的相同代码在运行 iOS5.0.1 的 iPad 上没有显示内存泄漏。
  • 你有没有找到解决这个问题的方法?
  • 我遇到的泄漏仅发生在通过 XCode 启动应用程序时。在 iPad 上正常启动时,它没有泄漏。用户报告了一个听起来像这样的崩溃,但我认为这两者无关。我浪费了一个月的恐慌试图解决。我打开了一个错误报告,但从未收到有用的回复。他们声称他们无法复制,但他们要么没有尝试,要么不理解。我发送了一个简单的项目,清楚地说明了问题。
  • 我明白了,非常感谢大卫的跟进。你是一个真正的救星

标签: iphone ios ipad ios5 memory-leaks


【解决方案1】:

我相信我终于找到了内存泄漏的原因。 在进行一些核心数据插入时,我发现了类似的行为。循环,创建许多被释放的对象。在 iPad 上运行时,虽然在应用程序因内存不足而崩溃之前没有明显的泄漏,但内存使用量会上升。但是当从设备启动时,它运行没有问题。

我突然想到它是从 Xcode 开始的。必须是项目中的调试设置。

原来问题是由于在调试时使用NSZombieEnabled 引起的。要在 Xcode 4 中禁用此设置,请右键单击方案,即 app>targetDevice,编辑方案,选择调试操作,参数选项卡。要启用NSZombieEnabled,将使用该名称创建一个值为YES 的环境变量,并启用该变量。要禁用它,请取消选中该复选框。

NSZombieEnabled 用于确定您是否尝试释放已释放的对象。为此,环境会跟踪所有已发布的对象。这会消耗内存,表现为内存泄漏。

禁用此功能后,我的应用程序在 iPad1 上被杀死之前会快速增长超过 115MB,现在可以愉快地坐在 24MB 且没有内存泄漏。

【讨论】:

  • 嗯...我有和你一样的代码,并且有大量的内存泄漏(这会使应用程序崩溃),但是僵尸对我来说已经关闭了......不过你是对的,当我手动启动应用程序,没问题......但如果我用 Xcode 启动它...... CRASH CRASH CRASH! :(
  • 同样的问题也发生在我身上,我使用的是 xCode 5,未选中 NSZombieEnabled。
【解决方案2】:

您发布的代码不应导致泄漏。泄漏肯定在其他地方。

我会推荐以下两个步骤:

  1. 发布您用于管理自动释放池的代码。
  2. 确保您在主线程中执行这些代码行(Apple's documentation 表示这实际上很重要)。

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 2015-02-17
    • 1970-01-01
    • 2012-12-23
    • 2017-02-28
    • 2017-04-14
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多