【问题标题】:Objective-C, what is the return value of getting a property from a nil pointer?Objective-C,从零指针获取属性的返回值是多少?
【发布时间】:2013-05-17 17:22:00
【问题描述】:

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

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

【问题讨论】:

  • 小心,你的NSArray *testArray 没有初始化为nil。
  • @s.bandara 在这个问题上——这正是他想要的。
  • @Abizern - 如果指针未初始化,则结果为“未定义”。
  • 如果这是用 ARC 编译的,那么编译器会插入指令来初始化 testArray = nil
  • @MartinR 酷,我不知道 :)

标签: objective-c pointers properties null


【解决方案1】:

从零接收器返回值

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

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

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

那么为什么 NSLog 会为第一条语句打印-1

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

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

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

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

【讨论】:

  • 但 count 不是属性 ;)
  • @Bastian,毕竟,Objective-C 中的点符号只是语法糖;)
  • @Wolfy,我知道.. 从技术上讲,你可以写像 NSArray *myarray = NSArray.alloc.init; 这样的东西,但你不应该;)
  • “来自 nil 接收者的其他可能值是......”并且不要忘记提到对于结构类型的返回值是未定义的(事实上,它使变量保持不变)
  • “结构类型没有这种定义的行为” 似乎并不完全正确。请参阅 stackoverflow.com/a/2696909/1402846developer.apple.com/library/content/documentation/Cocoa/…,其中说 “返回的结构的所有成员都初始化为零”
【解决方案2】:

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

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

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

【讨论】:

  • 这就是为什么搞乱类型是个坏主意。
  • @Wolfy 0 作为无符号整数 - 1(很可能)溢出到 MAXUINT。
  • @Joachim,确切地说,count 返回一个 NSUInteger,因此 testArray.count-1 产生了一个非常大的数字。因此,显然是神秘的结果。我会更新答案。
  • @JoachimIsaksson 和 Monolo,是的!这就是问题所在,已签名与未签名。
  • 次要备注:如果 count 是有符号整数,testArray.count - 1 = - 1 的结果也将是二进制的“全1”。关键是比较是作为有符号数还是无符号数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多