测试与NSNull的相等性

jun*_*ege 14 objective-c nsnull

下面是一个代码块,应该测试以查看字典是否为空,如果不是,则拉出正确的对象.但是,出于某种原因,尽管if检查失败,代码仍然执行.是否有一些关于NSNull我不理解的作品的怪癖,或者这是一个苹果虫?

if (svcUser && !(svcUser == (id)[NSNull null])) {
    return [svcUser objectForKey:@"access_level"];
}
Run Code Online (Sandbox Code Playgroud)

控制台响应:

(lldb) print svcUser && !(svcUser == (id)[NSNull null])
(bool) $0 = false
(lldb) continue
-[NSNull objectForKey:]: unrecognized selector sent to instance 0x2b51678
Run Code Online (Sandbox Code Playgroud)

JE4*_*E42 30

只需检查:

svcUser == [NSNull null]
Run Code Online (Sandbox Code Playgroud)

这是Apple在他们的文档中提到的方法.

  • 这给了我一个警告,使用http://stackoverflow.com/a/22825611/62来压制它. (5认同)

rma*_*ddy 18

NSNull是一个班级.和所有类一样,你必须使用isEqual:,而不是==看两个对象是否代表相同的值.

if (svcUser && ![svcUser isEqual:[NSNull null]]) {
    return [svcUser objectForKey:@"access_level"];
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是`[NSNull null]`是一个单例对象,所以你可以检查它,因为它们的引用是相等的.从控制台输出可以看出,`if`逻辑很好,但不知何故代码块仍在执行. (7认同)
  • 这似乎与Apple文档冲突"要测试空对象值,因此必须进行直接对象比较." https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html (3认同)
  • 我觉得我总是成功地使用 == 来表示 NSNull 。苹果的[示例代码](http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html#//apple_ref/doc/uid/TP40005153-SW1)似乎甚至赞同这个比较。 (2认同)
  • 但这是一个你不应该依赖的实现细节.使用`isEqual:`比依赖`==`工作更好更安全.在比较`NSString`文字时,这已经烧毁了很多人.@jungziege - 只是一个健全性检查,但你是100%确定崩溃是在发布的代码行而不是其他地方吗? (2认同)

Jos*_*hua 8

您可以使用以下方法进行检查:

 if(![svcUser isKindOfClass:[NSNull class]]){
    return [svcUser objectForKey:@"access_level"];
}
Run Code Online (Sandbox Code Playgroud)


Lir*_*dav 8

使用@ JE42的方法给我一个Xcode 5.1的警告.而是投下它:

(id)svcUser == [NSNull null]
Run Code Online (Sandbox Code Playgroud)