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:¤tVal 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非常有用的网站与聪明的人.
你不能适应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正在改变,因为您的代码会导致溢出到其他堆栈分配的变量中.