2009-10-26 78 views
1
-(void)invokeMethod 
{ 
    NSMethodSignature * sig = [[source class] instanceMethodSignatureForSelector:@selector(mySelector:)]; 
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:sig]; 

    [invocation setTarget:myTarget]; 
    [invocation setSelector:@selector(mySelector:)]; 

    MySubClassOfNSInvocationOperation * command = [[[MySubClassOfNSInvocationOperation alloc] initWithInvocation:invocation] autorelease]; 

    //setArgument retains command 
    [invocation setArgument:&command atIndex:2]; 

    //addOperation retains command until the selector is finished executing 
    [operationQueue addOperation:command]; 
} 


-(void)mySelector:(MySubClassOfNSInvocation*)command 
{ 
    //Do stuff 
} 

我不知道到底发生了什么,但NSInvocation & MySubClassOfNSInvocationOperation正在泄漏我该如何解决这个内存泄漏问题? NSInvocation的

当我删除行:

[invocation setArgument:&command atIndex:2]; 

它不泄漏,所以某种问题以传递命令作为参数。

回答

2

你可能有一个引用计数的环...其中command保留invocationinvocation保留command既不想要再次释放,直到自己dealloc方法的情况 - 通向何处,他们从来没有得到释放的情况。

你需要决定哪一个在层次上高于另一个,并确保初级对象不保留高级。顺便提一下 - NSInvocation不会保留参数,除非您致电retainArguments。或者,您可以实施一个close方法,手动告诉一方释放另一方,打破循环。

在我自己的一个项目中发现了NSInvocation这个确切问题后,我写了一篇文章“Rules to avoid retain cycles”。

+0

完美。谢谢 – 2009-10-26 14:44:36

-1

看来,setArgument方法保留缓冲区(在这种情况下 - 您的命令对象)。设置后可以尝试释放命令。但你应该保重)。当他的应用程序未在新的iPhone OS上运行时,我的朋友感到困惑,因为他通过添加一行附加的发行消息来纠正了Apple的泄漏。当苹果在新的操作系统做出修正,这条线是崩溃的应用程序)

+0

感谢您的回应,但尝试过,它最终被释放两次并崩溃。 – 2009-10-26 11:13:54

-2

什么跟在这条线的额外Ampersand的原因:

[invocation setArgument:&command atIndex:2]; 

你传递一个指针到A-你的命令的指针。这对我来说似乎是错误的。

+1

不 - 正确的http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html#//apple_ref/occ/instm/NSInvocation/setArgument:atIndex : – 2009-10-26 11:42:05

+0

具体“当参数值是一个对象时,将一个指针传递给应该从中复制对象的变量(或存储器):” – 2009-10-26 11:42:52

+0

我的不好 - 我纠正了。 – JBRWilkinson 2009-11-04 13:52:01