查找谁有对象的保留计数

时间:2009-02-25 15:51:24

标签: iphone objective-c cocoa cocoa-touch

我有一个UIViewController,当我实例化它时,它的retainCount为3。这让我觉得非常不正确。找出谁将retainCount提升到3的最佳方法是什么?我想像实例化对象应该给指针1,然后我想可能把它推到UINavigationController的堆栈上可能会碰到它(虽然不确定?),但第三个......是个谜。

4 个答案:

答案 0 :(得分:43)

亚当是对的,你不应该过分关注保留计数。

但是如果你有合理的需要来解决这样一个谜团,那么一个好的技术是将受影响的类子类化,这样你就可以为内存管理方法添加覆盖。

E.g。在UIViewController的子类中,您可以实现:

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

答案 1 :(得分:20)

不要直接依赖保留计数。发生的事情是,在初始化过程中,某些代码具有retain ed和autorelease d对象。因为您无法判断某个对象有多少次autorelease d,所以您实际上并不知道真实保留计数是什么。

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

只要您遵循Memory Management Programming Guide for Cocoa中规定的所有规则,就不会有问题。

答案 2 :(得分:8)

  

找出谁将retainCount提升到3的最佳方法是什么?

从错误的角度来看这个问题。这个 会让你感到困惑,而引导你误入歧途(并且可能正确地过去)实际问题,当确实有问题时。

最好考虑拥有对象的。您是否打算将对象保留为您自己的属性之一的值?如果是这样,那么你就是它的拥有者之一。如果没有,那么你不是。如果将对象传递给另一个对象以存储在其中一个属性中,则该另一个对象也是所有者。

这些所有权只是关系,所以很容易将它们直接放在脑海中。

  • “这是我的控制员之一。它拥有我的模型的根对象和一个或多个视图[controller] s。“
  • “这是一个观点。它拥有我模型的某些部分。“
  • “这是我模特的一部分。它只拥有原始对象。“
  • “这是我模特的另一部分。它拥有一些原始对象和其他一些模型。“

如果您已经掌握了所有权,那么无法写入内存泄漏,除非忘记releaseautorelease消息(可能发生在任何人身上) ,你几乎肯定不会写一个循环保留(两个互相保留的对象),除了明知而且有大量的评论和#warnings。

如果您还没有完成所有权,那么您可能已经编写了一个或多个内存泄漏或循环保留但您不知道。


编辑:为了回答实际问题,找出保留 - 并且可能随后自动释放 - 对象的最佳方法是使用Instruments的Allocations工具。有了它,您可以查看任何对象的历史记录,以查看其地址的每个分配,保留,自动释放,释放和取消分配。

答案 3 :(得分:1)

这不是100%的解决方案,但LLVM Clang静态分析器可以帮助追踪不正确的手动内存管理使用情况。在Static Analyzer和MallocDebug之间,您可以非常快速地跟踪内存管理问题。顺便说一句,即使仪器是新的热点,我发现MallocDebug更可靠。

您可以在此处找到LLVM Clang Static Analyzer:LLVM/Clang Static Analyzer