2009-10-26 81 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