I’m making a utility to get/set property values when the property has custom-named getters and setters. You can see the full context at line 279 here. The relevant snippet is here:
- (id) getFrom:(id) object {
NSMethodSignature *methodSig = [[object class] instanceMethodSignatureForSelector:[self getter]];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSig];
[inv setSelector:[self getter]];
[inv setTarget:object];
[inv invoke];
if ([self isObject]) {
id returnValue;
[inv getReturnValue:&returnValue];
return returnValue;
} else {
void *buffer;
NSUInteger length = [methodSig methodReturnLength];
buffer = (void *)malloc(length);
[inv getReturnValue:buffer];
NSValue *value = [NSValue valueWithBytes:buffer objCType:[methodSig methodReturnType]];
//FIXME: Memory leak for buffer! But if we free it, [value getValue:] is a dangling pointer.
//free(buffer)
return value;
}
}
The problem is that when the property is a scalar, I want to return an NSValue (much like Key-Value coding). However, the return value for NSInvocation is returned by reference, and according to the apple documentation (see the bottom), I can’t free the memory associated with the scalar while the NSValue still exists — but I’m returning the NSValue, so I don’t know when to free the memory.
Am I reading the documentation wrong? Does NSValue handle this automatically somehow? Or how do I free the memory properly in this situation?
Your must free
buffer.+valueWithBytes:objCType:copies the buffer sent in, so you can free buffer when you are done.You could also optionally use a
NSDataobject here, like this:This will mean that when the NSData object is deallocated, so will the buffer you created.
Proof that
+valueWithBytes:objCType:copies the buffer: