-(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
}
I don’t know exactly what is happening, but NSInvocation & MySubClassOfNSInvocationOperation are leaking
When I remove the line:
[invocation setArgument:&command atIndex:2];
It doesn’t leak, so some kind of problem with passing command as an argument.
You probably have a reference counted loop… a situation where
commandretainsinvocationandinvocationretainscommandand neither wants to release until their owndeallocmethod — leading to a situation where they never get freed.You need to decide which of the two is hierarchically senior to the other and make sure that the junior object does not retain the senior. Incidentally —
NSInvocationwon’t retain arguments unless you callretainArguments. Alternately, you can implement aclosemethod, manually telling one to release the other, breaking the cycle.I wrote the post “Rules to avoid retain cycles” after uncovering this exact issue with
NSInvocationin one of my own projects.