【问题标题】:Sending isEqual: to nil always returns NO发送 isEqual: 到 nil 总是返回 NO
【发布时间】:2011-05-06 17:20:00
【问题描述】:

如果你发送 isEqual: 到一个碰巧为 nil 的对象,你总是会得到 NO。

这是预期的行为吗?作为一个特性而不是一个错误,如果另一个对象也是 nil,我希望它返回 YES,否则返回 NO?从语义上看,这似乎是正确的行为。

如果我的预期不正确,建议的程序是什么?在发送 isEqual: (和朋友)之前检查 nil?

【问题讨论】:

    标签: objective-c cocoa null


    【解决方案1】:

    是的,这是预期的行为。任何到 nil 的消息都将返回一个结果,对于请求的类型,该结果相当于 0。因为布尔值的 0 是 NO,所以结果就是这样。

    【讨论】:

    • 我认为这是 Objective-C 设计中的一个缺陷,它只会让事情变得混乱且难以调试。但是,这就是它的工作方式,预期的行为也是如此。以某种方式绕过它
    • 你认为是缺陷,其他人认为是简化代码的伟大设计。
    【解决方案2】:

    这是 Objective-C 的预期行为。这基本上意味着这样做

    if ([nil isEqual:nil]) { ... }
    

    评估为否。尽管它没有意义,但在观察它时 - 尽管它很烦人 - 能够向 nil 发送消息实际上是关于 Objective-C 的非常酷的事情之一。有时可以为您节省大量代码。

    我的解决方案是在方便的地方定义这个宏

    #define IsEqual(x,y) ((x && [x isEqual:y]) || (!x && !y))
    

    所以当我需要测试两个对象是否相等时:

    if (IsEqual(obj1, obj2)) { ... }
    

    或不等于:

    if (!IsEqual(obj1, obj2)) { ... }
    

    希望这会有所帮助。

    【讨论】:

    • 我宁愿做那个宏:“(x == y) || [x isEqual:y]”,它也涵盖了所有情况,避免了常见特殊情况下的缓慢方法调用.顺便说一句,您仍然需要正常的构造来避免 x 和 y 的双重评估,毕竟它是一个宏。
    • @fishinear 我为一般的 isEqual 做了这个,但对于 NSStrings,它抱怨(“字符串文字的直接比较具有未定义的行为”),所以我做了#define IsStringEqual(left,right) ((!left && !right) || [left isEqualToString: right])
    【解决方案3】:

    预计,有两个原因:(1)在Objective-C中,向nil发送消息总是返回一个false-y值(nilNO00.0,等等;或者,更一般地说,0,可以根据方法的预期返回类型来解释); (2)nil代表一个未知值,两个未知值不一定相等。

    如果要查看对象是否为nil,请使用if (!obj)if (obj == nil)

    【讨论】:

    • 如果你使用if (!obj),为什么不重写最后一个表达式:if (obj)
    猜你喜欢
    • 2015-10-22
    • 2013-02-25
    • 2017-03-28
    • 2015-03-05
    • 2014-08-25
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多