-(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 command
retains invocation
and invocation
retains command
and neither wants to release until their own dealloc
method -- 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 -- NSInvocation
won't retain arguments unless you call retainArguments
. Alternately, you can implement a close
method, 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 NSInvocation
in one of my own projects.
It seems that setArgument method retains buffer (in this case - your command object). You can try to release command after setting. But you should be care). My friend was confused when his app wasn't run on new iPhone OS, because he corrected Apple's leak by adding one line with additional release message. And when apple made correction in new OS, this line was the reason of crashing the app)
What's with the extra ampersand on this line:
[invocation setArgument:&command atIndex:2];
You're passing a pointer-to-a-pointer of your command. That seems wrong to me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.