You can get void * from NSMutableData , as you can from malloc() , and essentially turn it into an instance variable so that the distribution lifetime is tied to the instance lifetime. I got this trick from Mike Ash . Lately I've been doing some NSInvocation monkey; this is in the category on NSInvocation (of course, you should use your own prefix for this method):
static char allocations_key; - (void *) Wool_allocate: (size_t)size { NSMutableArray * allocations = objc_getAssociatedObject(self, &allocations_key); if( !allocations ){ allocations = [NSMutableArray array]; objc_setAssociatedObject(self, &allocations_key, allocations, OBJC_ASSOCIATION_RETAIN); } NSMutableData * dat = [NSMutableData dataWithLength: size]; [allocations addObject:dat]; return [dat mutableBytes]; }
I'm not sure where the code you posted is; if you are in your own class, you do not need to deal with bits of related objects - just make allocations ivar.
Including this in your code:
NSUInteger length = [[invocation methodSignature] methodReturnLength]; if(length!=0){ void* returnBuffer = [self Wool_allocate:length]; [invocation getReturnValue:&returnBuffer]; return returnBuffer; } return nil;
If you use the linked route of an object, the allocations array will be freed if this instance is deleted. Otherwise, just put [allocations release] in your dealloc .
In addition, to answer the question posed, and not just solve the problem: free() will not work with any pointer that you did not receive from malloc() . When the pointer will be used in the block, I am sure that it will be copied, so you will get another pointer - still pointing to the same memory, but one that free() does not consider that it belongs. Thus, you get an error in not highlighting it.
source share