2009-10-26 4 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 сохраняет invocation и invocation сохраняет command и ни хочет не выпускать до своего собственного dealloc метода - ведущего к ситуации, в которой они никогда не получают освобожденный.

Вам нужно решить, какой из двух является иерархически старшим по отношению к другому, и убедитесь, что младший объект не удерживает старшего. Кстати - NSInvocation не будет сохранять аргументы, если вы не позвоните retainArguments. В качестве альтернативы вы можете реализовать метод close, вручную сообщая его, чтобы освободить другой, нарушив цикл.

Я написал сообщение "Rules to avoid retain cycles" после раскрытия этой точной проблемы с NSInvocation в одном из моих собственных проектов.

+0

Отлично. благодаря –

-1

Кажется, что метод setArgument сохраняет буфер (в данном случае - ваш объект команды). Вы можете попытаться освободить команду после настройки. Но вы должны быть осторожны). Мой друг был смущен, когда его приложение не было запущено на новом iPhone OS, потому что он исправил утечку Apple, добавив одну строку с дополнительным сообщением о выпуске. И когда яблоко сделал коррекцию в новой ОС, эта линия была причиной сбоев приложения)

+0

Спасибо за ответ, но попытался, он в конечном итоге был dealloc'd дважды и сработал. –

-2

Что с дополнительной амперсанд на этой линии:

[invocation setArgument:&command atIndex:2]; 

Вы передаете указатель-на-a- указатель вашей команды. Это кажется мне неправильным.

+1

Nope - это право http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html#//apple_ref/occ/instm/NSInvocation/setArgument:atIndex : –

+0

В частности «Когда значение аргумента является объектом, передайте указатель на переменную (или память), из которой должен быть скопирован объект:« –

+0

Мой плохой - я исправлен. – JBRWilkinson

Смежные вопросы