如何解决不同的行为-iPad与iOS模拟器上的NSDictionary
|| int a = 0;
NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:a],@\"A\",[NSNumber numberWithInt:a+=1],@\"B\",@\"C\",nil];
NSLog(@\"%@\",d);
在iPad上的结果:
{
A = 0;
B = 1;
C = 2;
}
结果在iOS模拟器中:
{
A = 2;
B = 2;
C = 1;
}
任何人都可以重现甚至更好地解释结果吗?
解决方法
函数或方法的参数求值顺序是不确定的,并且由编译器确定。这意味着不能保证第一个数字将在第二个数字之前创建,并且由Objective-c从c继承。看起来在iPad上,它们的执行顺序与代码中的顺序相同,但是对于模拟器,它们是以相反的顺序创建的。这是事件的顺序:
iPad:
评估第一个论点。这是一种方法。必须处理其参数:
参数是变量“ 1”。使用其当前值(0)。
评估第二个论点。这是一个常量字符串。加载其地址。
评估第三个论点。这是一种方法。必须处理其参数:
参数是一个表达式::2ѭ。递增
a
并返回其新值(1)。
评估第四个论点。这是一个常量字符串。加载其地址。
评估第五个论点。这是一种方法。必须处理其参数:
参数是一个表达式::2ѭ。递增a
并返回其新值(2)。
评估第六个论点。这是一个常量字符串。加载其地址。
模拟器:
评估第六个论点。这是一个常量字符串。加载其地址。
评估第五个论点。这是一种方法。必须处理其参数:
参数是一个表达式::2ѭ。递增a
并返回其新值(1)。
评估第四个论点。这是一个常量字符串。加载其地址。
评估第三个论点。这是一种方法。必须处理其参数:
参数是一个表达式::2ѭ。递增a
并返回其新值(2)。
评估第二个论点。这是一个常量字符串。加载其地址。
评估第一个论点。这是一种方法。必须处理其参数:
参数是变量“ 1”。使用其当前值(2)。
由于模拟器使用的i386调用约定是将参数以相反的顺序传递到堆栈上,所以我猜这就是为什么编译器以相反的顺序评估它们的原因。
为了解决您的问题,您应该在创建字典之前创建NSNumber对象,以强制编译器使用所需的顺序。
int a = 0;
NSNumber *numA = [[NSNumber alloc] initWithInt:a];
a += 1;
NSNumber *numB = [[NSNumber alloc] initWithInt:a];
a += 1;
NSNumber *numC = [[NSNumber alloc] initWithInt:a];
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:numA,@\"A\",numB,@\"B\",numC,@\"C\",nil];
[numA release];
[numB release];
[numC release];
NSLog(@\"%@\",d);
,这是未定义的行为。这些值没有正确的答案。顺序点之间的效果应用顺序不确定,参数列表中的逗号也不是顺序点。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。