Objective c 带NSValue和NSInvocation的free和malloc
当属性具有自定义命名的getter和setter时,我正在创建一个实用程序来获取/设置属性值。您可以在第279行看到完整的上下文。相关片段如下:Objective c 带NSValue和NSInvocation的free和malloc,objective-c,Objective C,当属性具有自定义命名的getter和setter时,我正在创建一个实用程序来获取/设置属性值。您可以在第279行看到完整的上下文。相关片段如下: - (id) getFrom:(id) object { NSMethodSignature *methodSig = [[object class] instanceMethodSignatureForSelector:[self getter]]; NSInvocation *inv = [NSInvocation invocati
- (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;
}
}
问题是,当属性是标量时,我希望返回一个NSValue(很像键值编码)。但是,NSInvocation的返回值是通过引用返回的,根据(见下图),当NSValue仍然存在时,我无法释放与标量关联的内存——但我返回的是NSValue,因此我不知道何时释放内存
我看错文件了吗?NSValue是否会自动处理此问题?或者在这种情况下如何正确释放内存?您必须释放
缓冲区+valueWithBytes:objCType:
复制发送进来的缓冲区,这样您可以在完成后释放缓冲区
您还可以选择在此处使用NSData
对象,如下所示:
NSData *data = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES];
这意味着当NSData对象被释放时,您创建的缓冲区也将被释放
证明+valueWithBytes:objCType:
复制缓冲区:
int *buffer = malloc(sizeof(int));
buffer[0] = 50;
NSValue *value = [NSValue valueWithBytes:buffer objCType:@encode(int)];
// sribble 'buffer'
buffer[0] = 1000;
free(buffer);
int test = 1000;
[value getValue:&test];
printf("%i", test); // outputs 50
我建议使用而不是malloc()
。你可以分配一些内存
NSMutableData * dat = [NSMutableData dataWithLength:length];
并以与malloc
'd块相同的方式使用它
void * buffer = [dat mutableBytes];
现在dat
拥有内存,这使它处于通常的Cocoa ref计数模式下。从这一点上,你可以做两件事中的一件
如果此对象是短期的,并且不会执行大量这样的分配,则名为allocations
或类似的NSMutableArray
ivar可以保存所有NSMutableData
实例,并且在解除分配其方法的对象时将释放这些实例
如果愿意,您可以将NSMutableData
的寿命与NSValue
本身或NSInvocation
联系起来,具体操作如下:
其中,dat_key
是一个在附近声明的静态
变量,您正在使用它的地址(如文档推荐的)
这使得associator(value,在本例中为)保留数据对象,并在数据对象本身被释放时将其释放。看起来比在释放缓冲区时简单地释放缓冲区要麻烦得多,因为NSValue复制了您发送的缓冲区。啊,所以我一定是看错了苹果的文档。谢谢,这确实简化了事情@贾吉尔:没问题!我个人也不知道答案,直到我写了我的测试应用程序!
objc_setAssociatedObject(value, &dat_key, dat, OBJC_ASSOCIATION_RETAIN);