methodSignatureForSelector上的内存泄漏

时间:2015-12-11 01:04:57

标签: ios objective-c memory-leaks automatic-ref-counting

当我使用仪器分配工具分析世代时,我有以下代码给我一个泄漏。

SEL sel = NSSelectorFromString(self.selector);

NSInvocation* invocation = [ NSInvocation invocationWithMethodSignature:[ self.target methodSignatureForSelector:sel ] ];

[ invocation setTarget:self.target ];
[ invocation setSelector:sel ];

[ invocation invoke ];

代码不检查返回值。有一些调用会返回对象,但这些调用只是被忽略了。

泄漏指向[NSMethodSignature methodSignatureForSelector]的调用。堆栈在此函数中显示一个48字节泄漏的calloc调用。

因为,我正在使用ARC,我的假设是这些缓冲区会自动被垃圾收集。但是有一个泄漏。在分配工具中最接近堆栈顶部的最后一个符号函数是

+[ NSMethodSignature signatureWithObjCTypes ]

这些在代码执行期间被称为数千次,并且泄漏正在堆积。任何帮助追踪这一点将不胜感激。

我的流程: 我使用了仪器 - 分配,检查了重新计数,然后运行了两代。分配工具允许您深入研究一代,然后选择在生成期间已分配(并且未释放)的缓冲区,然后您可以深入查看其重新计数历史记录。如果最后一个条目有引用计数,那么您可能有泄漏。现在只需要推断是否存在导致此对象泄漏的强循环。

2 个答案:

答案 0 :(得分:1)

编译器抱怨内存泄漏,但如果选择器返回void,则不会泄漏内存。看看这个discussion

尝试使用它:

[self.target performSelector:sel object:nil afterDelay:0.0];

答案 1 :(得分:1)

正如@Basheer_CAD所引用的主题所示,我将所有返回对象的NSInvocations更改为现在返回void。但它对泄漏没有任何影响。此外,分配工具似乎明确指出methodForSignature是罪魁祸首而不是调用的返回值。然后,我决定再运行几代,现在显然泄漏的次数减少了。在第3代,没有更多的泄漏。所以看起来这个泄漏与是否存在NSInvocation的返回对象无关。看起来methodSignatureForSelector正在分配一个48字节的缓冲区,并且这个缓冲区是针对Class对象缓存的。缓存可能服务于对相同方法签名的重复调用。我将忽略这种泄漏,因为它几代后就没有显示出来,并且会计算它对某种缓存的影响。 因此,如果出现这些泄漏,解决问题的最佳方法是运行几代,直到它再也无法显示。