开发者

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 = [[[MySubClassOfNSI开发者_开发知识库nvocationOperation 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜