在 Objective-C 中什么时候应该使用 nil 和 NULL?

这是示例代码:

NSDictionary *myDictionary = [NSDictionary dictionary];
NSNumber *myNumber = [myDictionary valueForKey: @"MyNumber"];
NSLog(@"myNumber = %@", myNumber); // output myNumber = (null)


if (myNumber == nil)
NSLog(@"test 1 myNumber == nil");


if (myNumber == NULL)
NSLog(@"test 2 myNumber == NULL");


if ([myNumber isEqual:[NSNull null]])
NSLog(@"test 3 myNumber == [NSNull null]");

什么时候应该使用 nil、 NULL 和[ NSNull NULL ] ?

126187 次浏览

在任何可以使用 null的地方都可以使用 nil。主要区别在于,您可以将消息发送到 nil,因此您可以在 null无法工作的某些地方使用它。

一般来说,只需使用 nil

他们的类型不同。它们都是零,但是 NULLvoid *nilidNil是 Class 指针。

NULL 和 nil 相等,但 nil 是一个对象值,而 NULL 是一个通用指针值(具体来说是 (void*)0)。[NSNull null]是一个在不允许使用 nil 的情况下代表 nil 的对象。例如,NSArray 中不能有 nil 值。因此,如果需要表示“ nil”,可以使用 [NSNull null]

详细说明@cobbal 的评论:

H 包含:

#ifndef nil
#define nil NULL
#endif

正如前面提到的,它们是相同的,但是根据编写相应框架的语言,我使用其中一种或另一种。

对于与 Objective-C 相关的所有内容,我使用 nil:

- (BOOL)doSomethingWithObjectsInArray:(NSArray *)anArray {
if (anArray == nil) return NO;


// process elements
...
}

然而,当从 C 框架(如 AddressBook 框架和 CoreFoundation)检查数据模型的有效性时,我使用 NULL:

- (BOOL)showABUnknownPersonVCForABRecordRef:(ABRecordRef)aRecord {
if (aRecord == NULL) return NO;


// set-up the ABUnknownPersonViewController and display it on screen
..
}

这样,如果我处理的是基于 Obj-C 或基于 C 的代码,我的代码中就会有一些细微的线索。

我发现了以下几点:

对象

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */

_ typees.h

#define __DARWIN_NULL ((void *)0)

Stddef.h

#undef NULL
#ifdef __cplusplus
#undef __null  // VC++ hack.
#define NULL __null
#else
#define NULL ((void*)0)
#endif

MacType.h

#ifndef NULL
#define NULL    __DARWIN_NULL
#endif /* ! NULL */
#ifndef nil
#define nil NULL
#endif /* ! nil */

看起来没什么区别,只是概念上的不同。

它们都是零类型的,在功能上,它们之间没有区别。 也就是说,

#define NULL ((void*)0)
#define nil ((id)0)

这是有区别的,但是只有对于你自己和其他阅读代码的人来说,编译器并不在乎。

还有一点,nil 是一个对象值,而 NULL 是一个通用指针值。

例如,当您使用类型(NSERror * *)的输出参数调用 Objective-C 方法时,请使用 NULL。

我在 web 上看到了很多示例代码,在这种情况下,人们提供的是 nil 而不是 NULL。这是因为它是一个指向指针的指针,因此不直接是 Objective-C 对象类型。如上所述,对于 Objective-C 对象类型,应该使用 nil。

Nil 是与对象绑定/对应的空值(Objective-C 中的 id 类型)。没有没有引用/地址,只有一个空值。

NSString *str = nil;

因此,如果我们处理的是一个对象,应该使用 nil。

if(str==nil)
NSLog("str is empty");

现在,在 Objective-C 中,无效用于 非对象指针非对象指针(就像 C 指针一样)。和 没有一样,无效没有价值也没有地址。

char *myChar = NULL;
struct MyStruct *dStruct = NULL;

因此,当我需要检查我的 结构(结构类型变量)是否为空时,我将使用:

if (dStruct == NULL)
NSLog("The struct is empty");

我们再举一个例子

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

对于 键值观测键值观测,上下文应该是 C 指针或对象引用。对于上下文,我们不能使用 没有; 我们必须使用 无效

最后,NSNull类定义了一个单例对象,用于表示集合对象中的 null 值(NSArray,NSDictionary)。[ NSNull 空]将返回 NSNull 的单例实例。基本上 [ NSNull 空]是一个合适的对象。

无法将 nil 对象插入到集合类型对象中:

NSMutableArray *check = [[NSMutableArray alloc] init];
[check addObject:[NSNull null]];
[check addObject:nil];

在第二行,我们不会得到任何错误,因为将 NSNull 对象插入到集合类型对象中是完全公平的。在第三行,我们将得到“ object can not be nil”错误。因为 nil 不是一个对象。

在现代 OS X 和 iOS SDK 中:

  • nilNilNULL在 Objective-C 和 in 中是相同的 Objective-C + + 在 C + + 11之前。
  • nilNilstd::nullptr是 在 Objective-C + + 中与 C + + 11相同。

在风格上,许多人喜欢将 nil用于 Objective-C 对象,而将 NULLnullptr用于其他指针类型。我自己现在在任何地方都使用 nil

[NSNull null]是一个 单身对象,用于在禁止将 nil作为值的情况下表示空值(通常在诸如 NSArrayNSDictionary之类的集合对象中)。数值和值编程主题: 使用 NSNull

在某些情况下是有区别的。

字面上,Null 是一个字符: ASCII 0。

Nil 等效于空白,没有值。

根据不同的编程环境,这可能会有很大的不同。

注意,if([NSNull null])返回 true

Nil 表示没有值,而 NULL 表示没有对象,

NSArray * array =@[@“ Hello World!”,@101,[ NSNULL null ] ;

这里[ NSNULL null ]是一个对象,意味着没有对象,同时您不能添加 nil 来表示没有对象。

也可以同时使用 nil 和[ NSNULnull ]进行检查。

这将帮助您理解 NIL、 NIL 和 null 之间的区别。

以下连结或会对你有所帮助:

Http://nshipster.com/nil/

Objective-C 对象的 nil-> 文本空值。

Objective-C 类的 Nil-> 文本空值。

C 指针的 NULL-> 文本空值。

NSNULL-> 用于表示空的单例对象。

基本上: 对象上的空指针和 Null: 表示其他类型指针

Nil 是指向无的对象指针。 尽管它们在语义上不同于 无效,但在技术上它们彼此之间是 相当于

在框架级别,Foundation 定义了 NSNull,它定义了一个类方法 + null,它返回单例 NSNull 对象。NSNull不同于 没有无效,因为它是一个 真的 对象,而不是一个零值。

此外,在 Foundation/NSObjecCRuntime.h 中,没有被定义为 同学们 指针 to nothing。

请参考此文件以获取更多的 info-Nil/Nil/NULL/NSNull