Objective c 将相等性测试为NSNull

Objective c 将相等性测试为NSNull,objective-c,nsnull,Objective C,Nsnull,下面是一个代码块,用来测试字典是否为空,如果不是,则拉出正确的对象。但是,出于某种原因,尽管if检查失败,代码仍然会执行。NSNull的工作原理是否有我不理解的怪癖,或者这是一个苹果bug if(svcUser&&!(svcUser==(id)[NSNull-null])){ 返回[svcUser objectForKey:@“访问级别”]; } 控制台响应: (lldb)打印svcUser&!(svcUser==(id)[NSNull]) (bool)$0=错误 (lldb)继续 -[NSN

下面是一个代码块,用来测试字典是否为空,如果不是,则拉出正确的对象。但是,出于某种原因,尽管
if
检查失败,代码仍然会执行。
NSNull
的工作原理是否有我不理解的怪癖,或者这是一个苹果bug

if(svcUser&&!(svcUser==(id)[NSNull-null])){
返回[svcUser objectForKey:@“访问级别”];
}
控制台响应:

(lldb)打印svcUser&!(svcUser==(id)[NSNull])
(bool)$0=错误
(lldb)继续
-[NSNull objectForKey:]:发送到实例0x2b51678的选择器无法识别

NSNull
是一个类。与所有类一样,必须使用
isEqual:
,而不是
==
来查看两个对象是否表示相同的值

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

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

 if(![svcUser isKindOfClass:[NSNull class]]){
    return [svcUser objectForKey:@"access_level"];
}
只需检查:

svcUser == [NSNull null]

这就是苹果在他们的报告中提到的方法。

使用@JE42的方法在Xcode 5.1中给了我一个警告。取而代之的是:

(id)svcUser == [NSNull null]

如果
svcUser
实际上是一个
NSNull
对象,对其调用
count
将导致崩溃。此外,目标是确保它不是
NSNull
对象。什么是
nsnull
?另外,使用
==
来比较这两个对象是不正确的。您需要使用
isEqual:
来比较两个对象。对不起,我没有注意到。但是已经更新了。起初,我以为您正在检查svcUser是否有值my Bad这是我最喜欢的方法,因为它不需要类型转换
if(svcUser!=nil&&![svcUser isEqualTo:[NSNull null null]]]
,您应该检查nil,检查NSNull是不够的。是的,但是
[NSNull]
是一个单例对象,因此,您可以通过任何一种方式进行检查,因为它们将是引用相等的。从控制台输出可以看出,
if
逻辑很好,但不知怎么的代码块仍在执行。我觉得我总是成功地将
=
用于
NSNull
。苹果似乎甚至赞同这种比较,但这是一个你不应该指望的实现细节。使用
isEqual:
比依靠
=
工作更好、更安全。过去,在比较
NSString
文本时,这让很多人感到痛苦@jungziege-只是一个理智的检查,但是你100%确定崩溃是在发布的代码行中,而不是在其他地方吗?我不会说这是一个实现细节,因为它被记录为单例。为了保持一致性,最好使用
isEqual:
,尤其是在
[NSNull-null]
而不是您自己的对象上调用它时。说到实现细节,
NSNull
目前似乎没有覆盖
isEqual:
,因此,我怀疑用
isEqual:
替换
==
会在目前产生不同的结果-我怀疑你在进行健全性检查,并且代码正在其他地方崩溃。这似乎与苹果的文档相冲突“要测试空对象值,因此必须进行直接对象比较。”尝试打破异常,并确保“未识别的选择器”被抛出到您认为的位置。您知道这里发生了什么吗?明确的解释-->这给了我一个警告,用于抑制它。