【问题标题】:Is if(obj && obj != nil) correct and necessary?if(obj && obj != nil) 是否正确且必要?
【发布时间】:2009-11-18 20:28:19
【问题描述】:

这个问题的两个部分

1) 这种理解正确吗?
"if (obj)" 正在测试指针是否不是 0x0,也就是设置为整数内存地址
"if (obj != nil)" 是比较对象的内存地址和通用 nil 对象的内存地址

2) 因此,在我不知道变量是否指向任何东西的情况下,如果是,我也不知道该对象是有效对象还是 nil。我想根据这些信息做各种各样的事情,而不仅仅是将消息传递给 obj,我意识到如果它为 nil 将是安全的。这段代码是否正确且必要?

if (obj && obj != nil) {
    // Do a bunch of things that should only happen if obj is pointing to a valid object
    [obj someMessage];
    [anotherObj someOtherMessage];
}

谢谢大家!

【问题讨论】:

    标签: iphone objective-c cocoa cocoa-touch null-test


    【解决方案1】:

    对吗?是的。必要的?不,Objective-C 只是 #defines nil(void *)0,这在 C 语言中是错误的。所以简单的写

    if (obj) {
        [obj someMessage];
        [anotherObj someOtherMessage];
    }
    

    就足够了。此外,由于 Objective-C 有消息吞噬nil,因此在某些情况下您可以简单地省略检查。 (例如,如果 if 块中没有第二行,您可以简单地不加选择地调用 [obj someMessage]。)

    【讨论】:

    • 你如何typedef 一个值? ;)
    • 哎呀。固定的。谢谢,帕维尔。
    • 其他一些答案似乎是正确的,但我认为这个答案在解释发生了什么方面做得最好。
    【解决方案2】:

    这是正确的,因为它会给你你期望的结果,但是多余的。只需使用就足够了:

    if (obj) {
    

    if (obj != nil) {
    

    【讨论】:

    • 非常感谢您的回答。赞成正确性,但我将标记 Ben 的答案,以解释其背后的原因。
    【解决方案3】:

    您可以简单地使用if (obj)。根据objc.hnil#define 对应于__DARWIN_NULL。查看/usr/include/sys/_types.h,我们看到__DARWIN_NULL 被定义为0L0(void *)0,具体取决于平台以及您使用的是C 还是C++ 编译器。但最终,nil 的计算结果始终为 false,因此更简单的 if (obj) 就足够了。

    【讨论】:

      【解决方案4】:

      不是对您的问题的直接回答,而是对第 2 部分暗示的问题的回答:除了发送消息并查看它是否执行您想要的操作之外,无法判断指针是否引用了“有效对象” .有各种各样的东西不是零,但对于大多数用途来说仍然不是“有效对象”。例如,一个对象变量可能指向:

      • 被释放的对象曾经存在的垃圾空间
      • 一个新对象被分配来代替变量应该指向的对象
      • 您不小心将变量设置为的 int
      • 您不小心将变量设置为的 C 字符串而不是 NSString

      如果出现上述任何一种情况,则无法在运行时进行测试。你必须确保你的代码没有错误,会使变量进入这样的状态。

      【讨论】:

      • 开发的时候可以在XCode中开启NSZombieEnabled设置。在某种程度上,这会在所有无效指针位置创建 NSZombie 实例,并且 NSZombie 只会抛出异常或为您发送给它们的所有消息提供一些其他主要错误指示。看到这个问题:stackoverflow.com/questions/535060/…
      • 澄清:NSZombieEnabled 确实有助于追踪这类错误,但它不会在“所有无效指针位置”处创建 NSZombie 实例。它使dealloc 将对象变成 NSZombies,而不是实际释放它们。当指针设置为一个从来不是对象的地址时,您仍然不会遇到僵尸异常,就像我在回答中提到的 int 或 C 字符串示例一样。
      • 当然有。出于我的目的,“有效对象”是指“对象的实例”。您可以使用 [obj isKindOfClass:[ObjClass class]],如果它为 nil,则为 false。我只是认为可能有 obj != nil 的捷径。就我而言,我知道该变量将始终是未初始化的、nil 或类 X 的实例。
      • 虽然我猜这会被认为是“向它发送消息”,所以是的,你是正确的,没有办法仅从指针中分辨出来。赞成。
      【解决方案5】:

      if (obj == nil) then if (obj) 将评估为假。两者都不需要。

      【讨论】:

      • 很抱歉投了反对票,我真的不是故意投反对票的,因为我点击了英国伟哥的回答。我无法取消投票,因为它已经太久了,但是当你编辑你的帖子时我会取消投票。
      猜你喜欢
      • 2011-11-13
      • 2010-12-30
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 2017-09-30
      相关资源
      最近更新 更多