为什么GameCenterManager.m中存在内存泄漏?

时间:2012-03-20 00:32:27

标签: objective-c memory-leaks automatic-ref-counting selector game-center

我在我的应用程序中使用Game Center,我发现gamecentermanager.m文件导致内存泄漏:

- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
assert([NSThread isMainThread]);
if([delegate respondsToSelector: selector])
{
    if(arg != NULL)
    {
        [delegate performSelector: selector withObject: arg withObject: err];
    }
    else
    {
        [delegate performSelector: selector withObject: err];
    }
}
else
{
    NSLog(@"Missed Method");
}
}

发生泄漏(根据编译器警告三角形),因为 performSelector (两者都是)选择器未知。有两件事我想知道

1)我直接从Apple的网站上的例子中复制了这个,所以如果Apple建立它,代码不会出现错误吗?

2)我该如何解决这个问题?

就像一个FYI,我使用的是使用LLMV编译器3.1和标准(armv7)架构的Xcode 4.3.1。我也在使用ARC。

如果您需要任何其他信息,请告诉我并提前感谢您。

1 个答案:

答案 0 :(得分:1)

这里的问题是ARC无法告诉您使用-performSelector:withObject:调用的方法的内存管理语义。在MRR下,它并不重要,因为预期调用代码会相应地处理它(例如,如果它是拥有的对象,则通过释放返回值)。但是在ARC下,编译器需要才能知道这些信息是正确的。我不记得-performSelector:withObject:的默认行为是什么,它可能只是将其视为非拥有参考,在这种情况下你实际上并没有泄漏。

处理这种委托模式的最简单方法是仍然使用-respondsToSelector:但是直接调用该方法,例如

if ([_delegate respondsToSelector:@selector(foo:)]) {
    [_delegate foo:self];
}

在您的情况下,方法本身实际上并不知道选择器是什么。你最好的选择可能是完全放弃这种方法,让它的前呼叫者处理与代表交谈。