我有一个UIViewController,当我实例化它时,它的retainCount为3。这让我觉得非常不正确。找出谁将retainCount提升到3的最佳方法是什么?我想像实例化对象应该给指针1,然后我想可能把它推到UINavigationController的堆栈上可能会碰到它(虽然不确定?),但第三个......是个谜。
答案 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的最佳方法是什么?
从错误的角度来看这个问题。这个 会让你感到困惑,而将引导你误入歧途(并且可能正确地过去)实际问题,当确实有问题时。
最好考虑拥有对象的。您是否打算将对象保留为您自己的属性之一的值?如果是这样,那么你就是它的拥有者之一。如果没有,那么你不是。如果将对象传递给另一个对象以存储在其中一个属性中,则该另一个对象也是所有者。
这些所有权只是关系,所以很容易将它们直接放在脑海中。
如果您已经掌握了所有权,那么无法写入内存泄漏,除非忘记release
或autorelease
消息(可能发生在任何人身上) ,你几乎肯定不会写一个循环保留(两个互相保留的对象),除了明知而且有大量的评论和#warnings。
如果您还没有完成所有权,那么您可能已经编写了一个或多个内存泄漏或循环保留但您不知道。
编辑:为了回答实际问题,找出保留 - 并且可能随后自动释放 - 对象的最佳方法是使用Instruments的Allocations工具。有了它,您可以查看任何对象的历史记录,以查看其地址的每个分配,保留,自动释放,释放和取消分配。
答案 3 :(得分:1)
这不是100%的解决方案,但LLVM Clang静态分析器可以帮助追踪不正确的手动内存管理使用情况。在Static Analyzer和MallocDebug之间,您可以非常快速地跟踪内存管理问题。顺便说一句,即使仪器是新的热点,我发现MallocDebug更可靠。
您可以在此处找到LLVM Clang Static Analyzer:LLVM/Clang Static Analyzer