我正在尝试使用NSInvocation
调用返回double
的方法。但我发现在64位iOS应用程序中它不起作用。它在OS X上,模拟器上(包括32位和64位),iPad 2上以及使用32位构建的iPad Air上工作。只有在iPad Air设备上进行64位构建时才会出现此问题。
以下是演示该问题的代码:
NSMethodSignature *signature = [NSString instanceMethodSignatureForSelector:@selector(doubleValue)];
for (int i = 0; i < 10; i++) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
NSString *str = [NSString stringWithFormat:@"%d", i];
[invocation setTarget:str];
[invocation setSelector:@selector(doubleValue)];
[invocation invoke];
union {
double d;
uint64_t u;
} d;
[invocation getReturnValue:&d.d];
NSLog(@"%lf, %llx", d.d, d.u);
}
预期输出
2013-11-09 22:34:18.645 test[49075:907] 0.000000, 0
2013-11-09 22:34:18.647 test[49075:907] 1.000000, 3ff0000000000000
2013-11-09 22:34:18.648 test[49075:907] 2.000000, 4000000000000000
2013-11-09 22:34:18.649 test[49075:907] 3.000000, 4008000000000000
2013-11-09 22:34:18.650 test[49075:907] 4.000000, 4010000000000000
2013-11-09 22:34:18.651 test[49075:907] 5.000000, 4014000000000000
2013-11-09 22:34:18.652 test[49075:907] 6.000000, 4018000000000000
2013-11-09 22:34:18.653 test[49075:907] 7.000000, 401c000000000000
2013-11-09 22:34:18.654 test[49075:907] 8.000000, 4020000000000000
2013-11-09 22:34:18.654 test[49075:907] 9.000000, 4022000000000000
iPad Air 64位构建的输出结果
2013-11-09 22:33:55.846 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.847 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.848 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.848 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.849 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.849 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.850 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.850 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.851 test[998:60b] 0.000000, 18710a969
2013-11-09 22:33:55.851 test[998:60b] 0.000000, 18710a969
浮点数值也会发生这种情况。
2013-11-09 23:51:10.021 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.023 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.024 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.024 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.025 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.026 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.026 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.027 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.027 test[1074:60b] -0.000000, 80000000
2013-11-09 23:51:10.028 test[1074:60b] -0.000000, 80000000
[invocation setTarget:[NSString stringWithFormat:@"%d", i]];
拆成两行吗?NSString *t=[NSString stringWithFormat:@"%d", i]; [invocation setTarget:t];
?我想知道目标字符串是否会过早释放。 - Sergey Kalinichenkodouble
变量参数与long long
变量参数的处理方式不同,那么你打印十六进制数的方法可能无法正常工作。最好定义一个union { double d; uint64_t x; } u;
,并像这样使用它:NSLog(@"%lf, %llx", u.d, u.x);
。 - Martin R[invocation retainArguments]
就可以解决它。 - jscs[NSString stringWithFormat:]
方法返回自动释放的对象,所以这不会是问题。 - Bryan Chen