使用ARC的iOS应用程序,查找谁是对象的所有者

时间:2012-12-31 17:45:27

标签: ios memory automatic-ref-counting memory-leaks

我正在编写一个使用ARC的应用程序,目前似乎有一些内存泄漏。谷歌搜索我发现了一些关于如何使用Inspector的提示。在那里,我可以看到大量的一些类的实例分配,我也可以看到一些关于如何分配对象的调用堆栈以及如何更改保留计数。

但似乎我看不到完整的调用堆栈,所以我不知道最终谁拥有该对象。它在我看来,这个所有者不知何故释放对象(或拥有可疑对象的对象)。

有人可以给我一个关于找到已分配对象的所有者的提示吗?

请注意,对象未标记为“已泄露”但已分配。对我来说,似乎是对象被泄漏,因为分配了稳定的新对象。

对于如何最好地进行和发现可疑泄漏的任何进一步帮助表示赞赏。

1 个答案:

答案 0 :(得分:46)

  1. 就谁“拥有”某个对象的学术问题而言,这只是维护strong对该对象的CFBridgingRelease()引用的人。

  2. 在查找应用程序泄漏方面,您可以在分析应用程序时使用Instruments中的“泄漏”工具(在Xcode的“产品”菜单上选择“配置文件”)。

  3. 如果它没有出现在“Leaks”中,那么你似乎必须决定它是否是一个强大的参考周期(以前称为保留周期),一些简单的逻辑错误(例如一些循环视图控制器中的引用,缓存大型对象等)或某些与Core Foundation相关的问题(除非您小心使用__bridge_transferviewDidLoad),否则ARC不会承担所有权。

    < / LI>
  4. 在使用Instruments找到分配来源方面,最能帮助我的两个技巧是:

    • 使用鼠标单击拖动(在6之前的Xcode版本中,您必须在执行此操作时按住选项键)以突出显示时间轴的一部分,以确定您想要的内容检查。您可能希望专注于分配中的一个峰值。例如,我在我的分配中发现了一个突破并突出显示它(这是一个非常简单的例子,我在viewDidLoad中创建了一个巨大的数组,但希望它能给你这个想法):

    enter image description here

    • 当您通过调用树进行检查时,选择“隐藏系统库”通常很有用,可以专注于您的代码。如果您双击Instruments中的方法名称(在我的示例中,这里将是UIImageView),那么Instruments会向您显示正在进行分配的代码:

    enter image description here

    然后,您可以双击相关的方法列表,它将精确地指向完成分配的代码。

    enter image description here

  5. 虽然这并未显示您发生了泄漏(即强引用循环或未能释放它的位置),但这种分析通常可以帮助您追踪泄漏对象的实例化位置,是追踪问题的第一步。


    如果你真的必须弄清楚谁“拥有”一个对象(即对象的强引用(或保留)发生的地方),Xcode 8有一个新的对象图功能。因此,调试应用程序,然后点击调试栏中的“调试内存图”图标(下面用红色圈出)。完成后,您可以选择左侧的对象,您可以看到显示对象所有权声明的对象图:

    enter image description here

    上面说明所选择的图像具有强大的引用,它同时显示了{{1}},但ViewController也保持了强引用。

    在早期的Xcode版本中,分析应用程序以通过Instruments运行它并选择“记录引用计数”选项。在Xcode 6中,它位于最右侧面板的“记录设置”选项卡上:

    enter image description here

    在Xcode 5及更早版本中,您必须单击“分配”工具旁边的i信息按钮才能看到此“记录引用计数”选项:

    enter image description here

    无论如何,您可以转到分配摘要,钻取一些未发布的对象(通过在分配工具中查看和对象时单击对象地址旁边的右箭头arrow) ,然后您将看到相关对象的保留和发布列表,如上所示。但是,只有在分析应用程序之前选择“记录引用计数”时才会捕获此内容。

    习惯跟踪保留计数需要一段时间,但如果你绝对需要知道强引用的确定位置,那么“记录引用计数”选项可以帮助你。