NSValue:getValue:奇怪的行为,为什么会这样?

Ale*_*der 3 objective-c nsinvocation

我尝试将CGRect传递给NSInvocation(setArgument:atIndex :).我用NSValue包装它,推送到NSArry,然后从NSArray获取并使用NSValue(getValue :).调用(getValue :)方法会导致更改前声明的索引NSInteger i.任何人都可以说为什么会这样?

 NSString className = @"UIButton";
    Class cls = NSClassFromString(className);
    cls pushButton5 = [[cls alloc] init];
    CGRect rect =CGRectMake(20,220,280,30);
    NSMethodSignature *msignature1;
    NSInvocation *anInvocation1;

    msignature1 = [pushButton5 methodSignatureForSelector:@selector(setFrame:)];
    anInvocation1 = [NSInvocation invocationWithMethodSignature:msignature1];

[anInvocation1 setTarget:pushButton5];
[anInvocation1 setSelector:@selector(setFrame:)];
NSValue* rectValue = [NSValue valueWithCGRect:rect];
NSArray *params1;
params1= [NSArray arrayWithObjects:rectValue,nil];
id currentVal = [params1 objectAtIndex:0];
NSInteger i=2;
if ([currentVal isKindOfClass:[NSValue class]]) {
    void *bufferForValue;
    [currentVal getValue:&bufferForValue];
    [anInvocation1 setArgument:&bufferForValue atIndex:i];
}else {
    [anInvocation1 setArgument:&currentVal atIndex:i];
}
[anInvocation1 invoke];
Run Code Online (Sandbox Code Playgroud)

当这个(getValue:)方法实现'i'的值从2更改为类似的东西:1130102784,并且(setArgument:atIndex:)我有一个SIGABRT因为索引i超出界限.

那么为什么要[NSValue getValue:(*void) buffer]改变其他变量呢?

(PS我在功能中这样做,所以我简化了一个例子并直接初始化数组.如果我直接设置atIndex:2,它工作得很完美.但是我很难过,我简化了一点,我需要将i传递给atIndex: )


感谢Tom Dalling(特别是)和塞尔吉奥问题解决了.我删除了这个:

void *bufferForValue;
[currentVal getValue:&bufferForValue];
[anInvocation1 setArgument:&bufferForValue atIndex:i];
Run Code Online (Sandbox Code Playgroud)

并粘贴这个

NSUInteger bufferSize = 0;
NSGetSizeAndAlignment([currentVal objCType], &bufferSize, NULL);
void* buffer = malloc(bufferSize);
[currentVal getValue:buffer];
[anInvocation1 setArgument:buffer atIndex:i];
Run Code Online (Sandbox Code Playgroud)

谢谢.Stackoverflow.com非常有用的网站与聪明的人.

Tom*_*ing 8

你不能适应NSRect一个void*.正确的代码是:

NSRect buffer;
[currentVal getValue:&buffer];
Run Code Online (Sandbox Code Playgroud)

或者,如果您不知道NSValue对象的内容:

NSUInteger bufferSize = 0;
NSGetSizeAndAlignment([currentVal objCType], &bufferSize, NULL);
void* buffer = malloc(bufferSize);
[currentVal getValue:buffer]; //notice the lack of '&'
//do something here
free(buffer);
Run Code Online (Sandbox Code Playgroud)

i正在改变,因为您的代码会导致溢出到其他堆栈分配的变量中.