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

Tor*_*ohr 13 memory memory-leaks ios automatic-ref-counting

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

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

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

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

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

Rob*_*Rob 47

  1. 关于谁"拥有"一个对象的学术问题,这只是维护strong对该对象的引用的人.

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

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

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

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

    在此输入图像描述

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

    在此输入图像描述

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

    在此输入图像描述

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


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

在此输入图像描述

上面说明了所选择的图像具有强大的参考UIImageView,它所呈现的位置,以及ViewController也保持强大的参考.

在早期的Xcode版本中,配置应用程序以通过Instruments运行它并选择"记录引用计数"选项.在Xcode 6中,它位于最右侧面板的"Record settings"选项卡上:

在此输入图像描述

在Xcode 5及更早版本中,您必须单击 一世 分配工具旁边的信息按钮,以查看此"记录引用计数"选项:

在此输入图像描述

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

需要一段时间才能习惯以这种方式跟踪保留计数,但如果您绝对需要知道强引用的建立位置,"记录引用计数"选项可以帮助您.

  • 超棒-特别是显示保留历史的技巧。为什么到底这个如此有用的功能被这样隐藏起来,甚至在默认情况下都没有打开? (2认同)