说明:
今天遇到一个特别的Bug:
NSArray *array;
// 定义 array 为:存有 100 个数的数组;
NSInteger index = -1;
if (index >= array.count) {
NSLog(@"index >= 100");
} else {
NSLog(@"index < 100");
}
// 打印:index >= 100
显然,结果和我们期待的很不一样:难道不应该是-1 < 100
吗?经过一番查证,终于找到了问题所在,特此以记之。
问题详述:
-
NSArray.count
的类型为NSUInteger
.// NSArray.h 中 count 属性如下: @property (readonly) NSUInteger count;
- 若给
NSUInteger
型变量赋值为-1
,它将被自动转换成NSUInteger
的最大值,且自-1
向下一一对应.NSUInteger a = 0; a = 2; NSLog(@" a=2 === %lu",(unsigned long)a); a = 1; NSLog(@" a=1 === %lu",(unsigned long)a); a = 0; NSLog(@" a=0 === %lu",(unsigned long)a); NSLog(@""); a = -1; NSLog(@"a=-1 === %lu",(unsigned long)a); a = -2; NSLog(@"a=-2 === %lu",(unsigned long)a); a = -3; NSLog(@"a=-3 === %lu",(unsigned long)a); a = -4; NSLog(@"a=-4 === %lu",(unsigned long)a); a = -5; NSLog(@"a=-5 === %lu",(unsigned long)a); NSLog(@""); a = -1; a = a - 18446744073709551615; //编译器警告18446744073709551615太大不能放进NSInteger,会自动转换为NSUInteger NSLog(@"a(= -1) - 18446744073709551615 = %lu",(unsigned long)a); // 打印结果如下: // a=2 === 2 // a=1 === 1 // a=0 === 0 // // a=-1 === 18446744073709551615 // a=-2 === 18446744073709551614 // a=-3 === 18446744073709551613 // a=-4 === 18446744073709551612 // a=-5 === 18446744073709551611 // // a(=-1) - 18446744073709551615 === 0
- 当
NSInteger
与NSUInteger
进行运算时,编译器会自动将NSInteger
转换成对应的NSUInteger
,这便是造成文章开头所提出的,产生与直觉相悖结果的原因.NSInteger b = -1; NSUInteger ub = 0; if (b > ub) { NSLog(@"-1 > 0"); } else { NSLog(@"-1 < 0"); } // 打印:-1 > 0
解决方法:
若必要,在拿
NSInteger
与NSUInteger
进行运算时,需手动将NSUInteger
转型为NSInteger
.
NSInteger b = -1;
NSUInteger ub = 0;
if (b > (NSInteger)ub) {
NSLog(@"-1 > 0");
} else {
NSLog(@"-1 < 0");
}
// 打印:-1 < 0