Objective-C,从nil指针获取属性的返回值是什么?

Wol*_*lfy 1 null pointers properties objective-c

我一直认为向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);
Run Code Online (Sandbox Code Playgroud)

输出是

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
Run Code Online (Sandbox Code Playgroud)

虽然第一行是有道理的,但第二行却没有.我错过了什么?

编辑:感谢@JoachimIsaksson和@Monolo指出(双关语)我正确的方向.问题实际上是签名v.无符号,以下代码显示:

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);
Run Code Online (Sandbox Code Playgroud)

输出是

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
Run Code Online (Sandbox Code Playgroud)

WDU*_*DUK 5

从零接收器返回值

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

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

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

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

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

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

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

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

  • @Bastian,毕竟Objective-C中的点符号只是语法糖;) (2认同)
  • @Wolfy,我知道..从技术上讲,你可以编写像`NSArray*myarray = NSArray.alloc.init;`但你不应该写的东西;) (2认同)