2009-10-26 3 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 
} 

Je ne sais pas exactement ce qui se passe, mais NSInvocation & MySubClassOfNSInvocationOperation fuientComment puis-je résoudre cette fuite de mémoire? NSInvocation

Lorsque je supprime la ligne:

[invocation setArgument:&command atIndex:2]; 

Il ne fuit pas, donc une sorte de problème avec passer la commande comme argument.

Répondre

2

Vous avez probablement une boucle de référence compté ... une situation où commandinvocation et conserve invocation conserve command et ne veut libérer jusqu'à ce que leur propre méthode dealloc - conduisant à une situation où ils se libérés jamais.

Vous devez décider lequel des deux est hiérarchiquement supérieur à l'autre et vous assurer que l'objet junior ne conserve pas l'aîné. Incidemment - NSInvocation ne conservera pas d'arguments sauf si vous appelez retainArguments. Vous pouvez également implémenter une méthode close, en indiquant manuellement l'un pour libérer l'autre, en interrompant le cycle.

J'ai écrit le post "Rules to avoid retain cycles" après avoir découvert ce problème avec NSInvocation dans un de mes propres projets.

+0

Parfait. Merci –

-1

Il semble que la méthode setArgument conserve la mémoire tampon (dans ce cas - votre objet de commande). Vous pouvez essayer de libérer la commande après le réglage. Mais vous devriez être prudent). Mon ami était confus lorsque son application n'était pas lancée sur le nouvel iPhone OS, car il corrigeait la fuite d'Apple en ajoutant une ligne avec un message de sortie supplémentaire. Et quand Apple a fait une correction dans le nouveau système d'exploitation, cette ligne a été la raison de plantage de l'application)

+0

Merci pour la réponse, mais essayé, il finit par être dealloc'd deux fois et se bloque. –

-2

Ce qui est avec l'esperluette supplémentaire sur cette ligne:

[invocation setArgument:&command atIndex:2]; 

vous passez un pointeur à a- pointeur de votre commande. Cela me semble faux.

+1

Non, c'est juste http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html#//apple_ref/occ/instm/NSInvocation/setArgument:atIndex : –

+0

Plus précisément "Lorsque la valeur de l'argument est un objet, passez un pointeur vers la variable (ou la mémoire) à partir de laquelle l'objet doit être copié:" –

+0

Mon mauvais - Je suis corrigé. – JBRWilkinson