Objective c 带NSValue和NSInvocation的free和malloc

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

当属性具有自定义命名的getter和setter时,我正在创建一个实用程序来获取/设置属性值。您可以在第279行看到完整的上下文。相关片段如下:

- (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);