在Objective-C中与null比较

8

我开始发现我的代码中充斥着:

if([p objectForKey@"somekey"] != [NSNull null]) {

}

有没有更短的(按字符计算)比较方法来判断 NULL?

背景:我正在使用 SBJson 库来解析一个 JSON 字符串,但其中某些键经常出现 null 值(这是设计如此的)。


objectForKey方法不会返回[NSNull null],而是返回nil。 - jarmod
1
如果字典中包含[NSNull null],则返回该值。 - Rob Napier
1
除非存储在@"someKey"中的对象是NSNull - Mike D
1
这里似乎有关于楼主问题的混淆。请阅读“背景”。他正在询问他想要问的内容。 - Rob Napier
2
我想重新打开这个问题。它不是重复的。问题不在于NSNull与nil的区别,而在于测试NSNull的程序员高效方法。 - Rob Napier
显示剩余4条评论
7个回答

7

虽然没有内置的方法,但创建一个名为MYIsNull()的函数来实现您想要的比较是合理且简单的。只需要考虑在键缺失的情况下要返回什么。

您也可以将-null转换为nil。例如,可以在NSDictionary上添加一个类别,如下所示:

- (id)my_nonNullObjectForKey:(NSString *)key {
   id value = [self objectForKey:key];
   if ([value isEqual:[NSNull null]) {
     return nil;
   }
   return value;
}

我喜欢这个解决方案。我们Objective-C程序员更习惯处理nil,并且能够使用我们通常的模式,比如if (!myString) ...是一个很大的优势。 - bdesham
4
请在NSDictionary中添加该类别前缀。 - bbum
1
请避免类方法名称冲突。在http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html阅读“避免类方法名称冲突”。这真的很重要,我曾因此遭受过很大的打击。 - Rob Napier

5

我会使用

if([[p objectForKey@"somekey"] isEqual:[NSNull null]] || ![p objectForKey@"somekey"]) {
    // NSNull or nil
} else {
    // Stuff exists...Hurray!
}

看起来它能工作,因为[NSNull null]实际上是一个“对象”。希望能对你有所帮助!


2
虽然编码更好,但它实际上与 OP 的目标相反(因为它比替换的内容更长)。 - Rob Napier
2
这是最佳解决方案。 - Mike D
这真的没有回答实际问题吗? - James Webster

3
不,你必须测试是否为NSNull。但是,如果你发现你的代码被它弄得很混乱,你可能想要为其创建一个#define
还要注意,如果p是nil,或者p没有someKey的值,那么[p objectForKey@"somekey"] != [NSNull null]评估为YES
所以你可能需要像这样做:
#define IsTruthy(X) ( X && (X != [NSNull null]) )

1

有没有更短的NULL比较方式(字符方面)?

[NSNull null] 是13个字符。你可以说:

NSNull.null // << 11
(id)kCFNull // << 11

或者创建一个函数:
IsNSNull([p objectForKey@"somekey"]) // << 10 in this case and requires no ==, !=

或者(恐惧地)使用一个分类:
[p objectForKey@"somekey"].mon_isNSNull // << 13 in this case, but requires no ==, !=

在处理 nil 接收器时,请注意如何命名该类别。


0

如果你只是担心打字所花费的时间,可以考虑使用宏:

#define ISNULL(key) [p objectForKey:key] == [NSNull null]

那么

if (!ISNULL(@"somekey")) ...

0

由于您正在使用SBJSON,因此您可以轻松更改其代码 - 您拥有源代码。

我实际上修改了SBJSON解析器以跳过[NSNull null]值。它们不会添加到字典中,当我调用objectForKey:时,我永远不会得到[NSNull null],我只会得到nil。然后,在大多数情况下,我甚至不必检查该值是否为nil,因为在nil上调用方法通常会给出我期望的结果。


-4

我相信你可以直接说

if ([p objectForKey:@"somekey"]) {

}

我不常使用NSNull,所以我不能百分之百确定,但我认为它测试为假,而任何其他对象测试为真。


4
如果“someKey”的值实际上是NSNull,则此测试将通过。这个if语句相当于 if ([p objectForKey:@"someKey"] == nil ) - Mike D
1
我给你点了个踩,因为我相当确定这是不正确的。你能否测试一下以确保它是正确的? - bdesham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接