I'm using NSInvocation
to get some method returns, and unfortunately I seem to have a leak, but can't figure out how to free the void*
I'm allocating, after I've returned it from NSInvocation
.
In the following implementation I tried to free it with a block that gets performed on the next run loop, but I get a crash due to returnBuffer
not being allocated.
Why can't I free returnBuffer
in the block, and if it hasn't been allocated why is it getting through returnBuffer!=NULL
?
This is a special method that has to do with IMP
swizzling so I DON'T know the method return type. Putting it in NSData
or something will not work.
NSUInteger length = [[invocation methodSignature] methodReturnLength];
if(length!=0){
void* returnBuffer = (void *)malloc(length);
[invocation getReturnValue:&returnBuffer];
if(returnBuffer!=NULL){
void(^delayedFree)(void) = ^{ free(returnBuffer); };
[[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree];
}
return returnBuffer;
}
return nil;
ANSWER
Got it to work the following way thanks to Josh's -[NSMutableData mutableBytes]
trick
NSUInteger length = [[invocation methodSignature] methodReturnLength];
if(length!=0){
NSMutableData * dat = [[NSMutableData alloc] initWithLength:length];
void* returnBuffer = [dat mutableBytes];
[invocation getReturnValue:&returnBuffer];
void(^delayedFree)(void) = ^{ [dat release]; };
[[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree];
return returnBuffer;
}
return nil;