在我的部分代码中,我编写了一个简单的for
循环来迭代数组中的元素(所有NSMutableDictionary
s),我发现循环已执行,即使条件基本上是1 < -1
所以我编写了以下代码,以测试此问题的有效性:
NSMutableArray* arr = [[NSMutableArray alloc] init];
NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));
输出结果为:
COUNT: 0 | 1
这实质上意味着计数为0,而1则小于-1。
我想也许是因为数组是刚刚初始化的,并且添加和删除对象可能会改变这一点,所以我继续这样做:
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:@1];
[arr removeObject:@1];
NSLog(@"COUNT: %d | %i", arr.count, 1 < (arr.count - 1));
结果仍然相同:
COUNT: 0 | 1
我想到的可能原因是:
我非常怀疑它是最后两个案例中的哪一个,我仍然想知道为什么这种情况。
答案 0 :(得分:7)
arr.count
是无符号整数值(类型NSUInteger
)。使用无符号算术时,(0 - 1)
会回绕到一个非常大的正数,而不是-1
。
如果将值转换为有符号整数,您可能会看到预期的结果:
NSLog(@"COUNT: %d | %i", (int)arr.count, 1 < ((int)arr.count - 1));
有关处理此常见错误来源的一些方法,请参阅此主题:Constant bugs from [NSArray count] being unsigned
答案 1 :(得分:4)
发生这种情况的原因是左侧的1
被视为无符号。反过来,这是因为arr.count
是无符号类型,因此表达式arr.count-1
也是无符号的。从无符号零中减去1
时,会出现下溢,结果是一个非常大的正数。
为了避免这样的问题,在处理unsigned
类型的值时要非常小心减法。更喜欢添加到另一方 - 特别是,而不是写
if (a < unsignedB - c)
写
if (a+c < unsignedB)
答案 2 :(得分:3)
数组的count
属性为NSUInteger
类型,表示unsigned long
。表达式arr.count - 1
从无符号整数中减去1,因此结果也是无符号的。而不是-1,因为溢出而得到非常大的正数,而且这个数字大于1。
答案 3 :(得分:2)
[arr count]
返回(NSUInteger)
,这只是typedef unsigned long NSUInteger;
因此NSUInteger
不会有任何负数。值从0开始到某个最大值,它将像一个循环,如下所示
... | MAX-2 | MAX-1 | MAX | 0 | 1 | 2 | 3 | 4 | ...
-1 -1 -1 -1 -1 -1 -1
So, the math is like 2-1 = 1
1-1 = 0
0-1 = MAX
0-2 = MAX-1