【问题标题】:Objective C/iPhone : need "best practices" for debugging memory management bugsObjective C/iPhone:需要“最佳实践”来调试内存管理错误
【发布时间】:2010-01-13 00:01:19
【问题描述】:

所以...我编写了我的第一个 iPhone 游戏,其中可能包含 50 个谜题。

在每个谜题开始时,我创建了一些字符串、各种可变的指针数组,其中一些指向运行时创建的子视图。所有保留的变量都被声明为各种类属性。然后在拼图的最后,我删除了子视图,释放了分配给指针的所有内存,我的指针为零。然后为下一个谜题再次创建它们。

该应用程序在前 2、3、有时是 4 个谜题中运行良好,然后由于看似随机的错误访问错误等而崩溃,我正在努力追查。显然我对 iPhone 内存管理不太了解 :)

那么,我需要关于调试的建议吗?你是否通读了每一行代码并记下了每个分配、每个子视图、一种手动保留计数?我是否搜索 allocs 并将它们与发布相匹配?还是有其他技术?

我不希望我的问题得到答复,但希望得到任何提示和技巧!谢谢!

【问题讨论】:

    标签: iphone objective-c debugging memory-management


    【解决方案1】:

    正如其他人所指出的,静态分析器有很大帮助 - 在 Snow Leopard 中,您只需运行“构建和分析”并通读结果即可。

    我会说下一步将是仪器,但您的问题似乎更像是提前释放对象而不是泄漏内存。要追踪这一点,最好的办法是启用僵尸检测。

    在 XCode 中,在项目浏览器中打开“可执行文件”项,右键单击您的可执行文件并选择“获取信息”。然后转到“参数”选项卡,转到下半部分并添加一个新的环境变量。将其命名为“NSZombieEnabled”并将值设置为“YES” - 确保它也被选中,但如果您正在创建它,它应该是默认的。

    现在,当您运行应用程序时,每当您使用已发布的对象时,调试器都会在您收到 BAD_ACCESS 消息之前停止,您可以看到正在发布的内容不应该发布。

    完成后,您需要取消选中可执行文件的 NSZombieEnabled 变量,因为系统在设置时不会真正释放任何内存。

    调试这些东西可能有点棘手,因为您必须找出释放对象的任何地方才能找到最终错误释放的位置。 Snow Leopard Instruments 对此有所帮助,因为 Object Alloc 与 NSZombieEnabled 一起工作,可以向您展示释放对象的所有位置。

    您还可以使用“泄漏”工具来查找您认为已释放对象但实际上没有释放的位置 - 尽管我在实践中发现大约一半的时间泄漏不会显示任何内容,因为除了泄漏,您还保留了对该对象的引用,因此泄漏不知道您确实有泄漏。只观察 Object Alloc 图,并在您认为应该释放内存的情况下选择爬升的区域可能是一个非常好的主意。

    【讨论】:

    • 此建议补充了 Johan 关于使用静态分析器的建议。根据他的建议,我尝试了静态分析器,发现了一些问题。现在还用 NSZombie 和仪器进行测试,到目前为止,一切都很好。切换刻度似乎不合适,但衷心感谢您的出色解释。
    • 感谢您提供 NSZombieEnabled 提示。这正是我所需要的。
    【解决方案2】:

    您是否对代码运行了静态分析器?那应该可以捕获大多数这些错误。在项目的 Xcode 构建选项中,启用 RUN_CLANG_STATIC_ANALYZER。

    【讨论】:

      【解决方案3】:

      静态分析器在拾取保留泄漏方面做得非常好。我倾向于使用 Apple Key A 来构建,它会在构建过程中自动进行分析。

      下一步是检查仪器。作为预提交过程的一部分,我建议您在 Instruments 中运行您的应用程序。您可以在应用程序运行时跟踪分配、检查泄漏、性能测试等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-25
        • 2012-03-28
        • 2013-11-08
        • 2011-05-04
        • 1970-01-01
        • 1970-01-01
        • 2010-12-07
        • 2010-09-07
        相关资源
        最近更新 更多