1

我一直认为向 nil 指针发送消息通常会返回 0。所以这同样适用于属性。但是这个代码片段似乎与我的假设相矛盾

NSArray *testArray;
NSInteger i = 0;
NSLog(@"testArray.count-1=%ld", testArray.count-1);
NSLog(@"i<testArray.count-1=%d", i<testArray.count-1);

输出是

2013-05-22 11:10:24.009 LoopTest[45413:303] testArray.count-1=-1
2013-05-22 11:10:24.009 LoopTest[45413:303] i<testArray.count-1=1

虽然第一行有意义,但第二行没有。我错过了什么?

编辑:感谢@JoachimIsaksson 和@Monolo 为我指出(双关语)正确的方向。问题实际上是有符号和无符号的,下面的代码显示了它:

NSArray *testArray;
NSInteger i = 0;
unsigned ucount = 0;
int count = 0;

NSLog(@"testArray.count-1=%ld", testArray.count-1);
NSLog(@"i<testArray.count-1=%d", i<testArray.count-1);
NSLog(@"i<ucount-1=%d", i<ucount-1);
NSLog(@"i<count-1=%d", i<count-1);

输出是

2013-05-22 11:26:14.443 LoopTest[45496:303] testArray.count-1=-1
2013-05-22 11:26:14.444 LoopTest[45496:303] i<testArray.count-1=1
2013-05-22 11:26:14.444 LoopTest[45496:303] i<ucount-1=1
2013-05-22 11:26:14.445 LoopTest[45496:303] i<count-1=0
4

2 回答 2

5

从 nil 接收器返回值

当访问属性或从 nil 对象读取返回值时,您将获得它们的默认值。对于任何数字返回类型,这通常为 0。因此,当它被 nilled 时获取数组的计数将产生 0。来自 nil 接收器的其他可能值对于 BOOL 是 NO,对于对象返回类型是 nil。返回的结构将所有成员初始化为零。

数组计数是无符号的...

现在,您需要记住数组计数返回 NSUInteger。由于这是无符号的,如果你从 0 中减去,你将下溢,并得到一个非常大的数字。

为什么 NSLog 打印-1第一条语句呢?

这是因为您使用@"%ld"了 ,它指定了一个长符号整数。因此,该值被解释为有符号,这将导致 -1。变量的类型实际上表明它是一个无符号长整数,其格式说明符应该是@"lu". 使用它时,它会为我产生 18446744073709551615 (可能因平台而异)。

这对第二个 NSLog 语句有何影响?

考虑到第一个语句中发生的情况,第二个语句现在可能更有意义。您可能认为它是在比较0 < -1,结果为 NO,并且不应该产生结果 1。实际被比较的是0 < 18446744073709551615,结果为 YES。这就是为什么你得到 1 的结果。

这一切都归结为在 NSLog 中使用了不正确的格式标识符,这导致了如何解释该值的混乱。

于 2013-05-22T15:34:55.727 回答
3

它总是什么都没有:nil,零,否。

countJoachim Isaksson 在评论中NSUInteger也指出了返回类型。testArray.count-1预计为 -1,以二进制编码...111111(确切的位数取决于平台,以及代码是编译为 32 位还是 64 位)。然而,由于表达式是无符号的,它将被解释为一个非常大的数字——实际上是可以表示为无符号整数的最大可能数字。

这个非常大的数字,与变量相比时 i要大得多。因此输出。

于 2013-05-22T15:14:55.727 回答