简体   繁体   中英

How can I solve this memory Leak? NSInvocation

-(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM