我曾经使用调试器下的[myVar retainCount]验证我的一些变量是否具有预期的保留计数,尤其是对于没有自定义dealloc的var。
如何在ARC模式下执行此操作?你如何确保没有内存泄漏?
注意:我理解ARC应该为我处理这个问题,但生活远非完美,而在现实生活中,你有些对象有时会被第三方库分配(使用retain?)并且永远不会被解除分配。
我这样做的图片:
MyObj *myObj=[[MyObj alloc] init];
然后我打电话给
[somethingElse doSomethingWithMyObj:myObj];
以后,我做
myObj=NULL;
如果我的程序运行正常,我的期望是myObj正在被销毁,但似乎并非如此......
那么我该如何跟踪这一点,特别是如果我没有管理某些东西?
现在,关于工具:在没有重新启动mac并从头开始的情况下,在我的mac(使用5 Meg)上运行内存工具似乎非常困难。这真烦人!仪器甚至在程序启动之前就会一直崩溃,那么有没有替代解决方案呢?
答案 0 :(得分:98)
即使在ARC:
下,您也可以将CFGetRetainCount
与Objective-C对象一起使用
NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));
这是不对调试特别有用,for reasons amply described elsewhere。如果您需要了解保留和释放对象的位置,请使用分配工具查看this answer以获取帮助。
我发现检查保留计数实际上有用的唯一情况是dealloc
方法,当某些东西保留并自动释放被释放的对象时。这会在自动释放池耗尽后导致崩溃。您可以通过检查每条消息之前和之后的保留计数来查明原因。通过这种方式,我发现the observationInfo
method(它本身通常只对调试有用)保留和自动释放self
。但是,即使是这类问题通常也可以在不检查保留计数的情况下解决,只需将dealloc
的整个主体包裹在@autoreleasepool
块中即可。
但是,保留计数可用于了解某些类的实现。 (仅用于娱乐或好奇!不要依赖生产代码中未记录的实现细节!)
例如,请在@autoreleasepool
中的main
内立即尝试:
NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test
因此NSNumber
可能会缓存(或至少重用)某些实例。但不是其他人:
n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance. There could be weak
// or unretained references to it, but no other strong references.
NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again. New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.
您甚至可以发现NSNumber
如果您alloc
返回单身但未初始化:
n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.
(请注意,您还可以通过查看http://opensource.apple.com上提供的Core Foundation源代码了解有关NSNumber
的许多详细信息。但是,如果您查看保留,您知道可能会发现什么与Core Foundation中的对象无法免费桥接的对象数量?)
答案 1 :(得分:41)
你没有。 ARC为您处理内存管理,并且不允许您调用retainCount,即使您可以看到它,它返回的数字对您来说也毫无意义。如果您愿意,您应该使用Leaks and Allocations工具在Instruments中进行内存分析。这是查看和查看应用程序如何分配内存以及捕获内存中任何不当使用内存的最佳方式。
答案 2 :(得分:31)
任何事情都不应该使用retainCount,无论是否有ARC。
答案 3 :(得分:15)
使用“仪器”并通过搜索类别名称或指针地址找到要跟踪的对象,如果在“对象列表”中,则可以找到它。
找到它后,点击实例上的显示箭头。这将带您进入保留和关系的历史视图。
如果展开右侧详细视图,您还会看到每个保留/释放的callstack。
答案 4 :(得分:3)
我认为唯一的方法是使用Allocations工具分析您的应用程序。您需要单击信息描述符(左侧窗格中“分配”旁边的“i”),然后单击“记录参考计数”。然后,您可以对您的应用进行分析,并搜索您要检查的特定课程。从那里,您可以在“扩展详细信息”窗格中找到该类的每个实例的保留计数。
你也可以使用Leaks(因为我相信它是Allocations乐器的一种变体)。
答案 5 :(得分:2)
获取对象的retainCount
?
您可以创建断点并输入以下命令以获取对象的retainCount
po object.retainCount
答案 6 :(得分:0)
你没有。 Apple说你不需要为ARC处理它。