寻找哪些对象有对一个对象的保留计数

5

我有一个UIViewController,它在我实例化时的retainCount为3。这让我感到非常不正确。如何最好地找出是谁把retainCount增加到3?我想实例化对象应该给指针1,然后我想可能将其推入UINavigationController的堆栈可能会增加1(不确定?),但第三个。。。是个谜。

4个回答

43

Adam正确,您不应过于担心保留计数。

但是,如果您确实有解决此类问题的合法需求,一种好的技术是子类化受影响的类,以便可以添加覆盖内存管理方法。

例如,在UIViewController的子类中,您可以实现:

- (id) retain
{
    // Break here to see who is retaining me.
    return [super retain];
}

你怎么知道谁在保留这个对象?唯一的参数是self,不是吗? - quano
5
在调试器中查看堆栈跟踪。您将准确地看到是谁在调用retain。 - danielpunkass

20

永远不要直接依赖保留计数。在初始化过程中,某些代码已经 retainautorelease 了该对象。由于无法确定对象已被 autorelease 多少次,因此您实际上不知道真正的保留计数是多少。

保留计数应仅用作调试辅助工具,永远不应用作程序控制流。

只要您遵循Cocoa内存管理编程指南中规定的所有规则,就不会出现问题。


8
最好的方法是如何找到将retainCount增加到3的人?
这种方式是错误的。这会让你感到困惑,并使你偏离(并可能绕过)实际问题,即使确实存在问题。
更好地考虑谁拥有该对象。您是否打算将该对象保留为自己一个属性的值?如果是,则您是其所有者之一。如果不是,则不是。如果您将对象传递给另一个对象以存储在其属性中,则该其他对象也是所有者。
这些所有权只是关系,因此在您的头脑中轻松保持它们正确很容易。
“这是我的控制器。它拥有我的模型和一个或多个视图[控制器]的根对象。”
“这是一个视图。它拥有我的模型的某些部分。”
“这是我的模型的一部分。它仅拥有原始对象。”
“这是我模型的另一部分。它拥有一些原始对象和一些其他模型的位。”
如果您完全掌握了所有权,那么您只能通过忘记release或autorelease消息(任何人都可能遇到)来编写内存泄漏,而几乎肯定不会编写循环保留(两个对象互相保留),除非有意并带有大量注释和#警告。
如果您还没有解决所有权问题,则可能已经编写了一个或多个您不知道的内存泄漏或循环保留。
编辑:回答实际问题的最佳方法是使用Instruments的Allocations工具。使用它,您可以查看任何对象的历史记录,以查看其地址的每个分配,保留,autorelease,释放和释放。

1

这不是一个百分之百的解决方案,但LLVM Clang静态分析器可以帮助追踪手动内存管理使用不正确的问题。在静态分析器和MallocDebug之间,您可以快速成为追踪内存管理问题的专家。顺便说一句,尽管Instruments是新的热门工具,但我发现MallocDebug更加可靠。

您可以在这里找到LLVM Clang静态分析器:LLVM/Clang Static Analyzer


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接