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


170

这是示例代码:

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]?


4
它与目标C问题有关。
比兰奇

nil表示一种NULLfor objc实例。这样就可以标记特定的值,供objc实例或通用指针使用。鉴于类型管理和安全性,这将对您有很大帮助。
2011年

4
nilnull/ NULL相同-都定义为零。作为形式,nil在编写Objective-C和NULL编写常规C / C ++语句/调用时使用。 NSNull但是完全不同。它是一个单例对象,用作占位符,以表示“无”,例如,在NSDictionarys中不允许使用nil / null指针。
热门点击

请参阅链接,很好的解释[这里] [1] [1]:stackoverflow.com/questions/5908936/...
阿米尔

Answers:


114

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

通常,只需使用即可nil


12
从技术上讲,它们是完全相等的,您可以将消息发送到nil和NULL。习惯上,虽然通常使用nil来表示对象
cobbal

41
另外,在MacTypes.h中,还有#define nil NULL
cobbal

8
是的,正如cobbal所说,它们是相同的。它更是一个上下文引用,其中NULL是指向0x0的指针,nil是不存在的Objective-C对象,而Nil是不存在的Objective-C类,但从技术上讲,它们全都是0。而且,它不是NULL null-在Java或C#中为null,但在Objective-C中为null。
杰森·可可

16
这个被接受的答案未能承认那[NSNull null]是完全不同的野兽。引用NSNull类参考,“ NSNull类定义了一个单例对象,该对象用于表示集合对象中的空值(不允许nil值)。” 另请参阅“ 数字和值编程主题”的“ 使用NSNull”部分
罗布2012年

“主要区别在于您可以将消息发送到nil”-您也可以将消息发送到NULL

313

它们的类型不同。它们全为零,但是NULLvoid *nilid,并且Nil是Class指针。


14
最好的解释,我听说过这种区别(:谢谢
雅各布

3
这应该是公认的答案,不是因为有更多的赞成票,而是因为它对提出的问题有最好的解释。
James Mertz 2012年

5
NULLv的优雅描述nil,但这严重错过了标记re [NSNull null]。请参阅“ 数字和值编程主题”的“ 使用NSNull”部分和“ NSNull类参考”
罗布

两者似乎都是指向的指针void *。这里已经有一个不同的答案提到了这一点,但是如果您深入研究objc.h,就会发现这条线#define nill __DARWIN_NULL
gkb0986

1
这个答案听起来不错,但根据其他答案,这完全是错误的。
2014年

30

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

NSString *str = nil;

因此,如果我们要处理对象,则应使用nil。

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

现在NULL用于Objective-C中的非对象指针(如C指针)。像nil一样,NULL没有值或地址。

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指针或对象引用。在这里,我们不能使用nil;我们必须使用NULL

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

无法将nil对象插入集合类型对象。让我们举个例子:

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

在第二行中,我们不会出现任何错误,因为将NSNull对象插入集合类型对象中是完全公平的。在第三行,我们将得到“对象不能为零”错误。因为nil不是对象。


+1表示数组中nil / null的实际使用。
2014年

19

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


12

我发现以下内容:

objc.h

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

_types.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

MacTypes.h

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

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



7

它们都只是类型转换零。在功能上,它们之间没有区别。即

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

有所不同,但是仅对于您自己和其他阅读代码的人而言,编译器不在乎。

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


6

在现代OS X和iOS SDK中:

  • nilNilNULL在Objective-C和C ++ 11之前的Objective-C ++中相同。
  • nilNilstd::nullptr在带有C ++ 11的Objective-C ++中相同。

从风格上讲,许多人更喜欢将其nil用于Objective-C对象NULLnullptr其他指针类型。我自己现在nil在各处使用。

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



4

如前所述,它们是相同的,但是我使用一种或另一种取决于编写相应框架的语言。

对于与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的代码,我的代码中会有一些线索。


4

nil是什么都没有的对象指针。尽管从语义上与NULL不同,但它们在技术上彼此等效

在框架级别,Foundation定义了NSNull,它定义了一个类方法+ null,该方法返回单例NSNull对象。NSNullnilNULL不同,因为它是一个实际 对象,而不是零值。

此外,在Foundation / NSObjCRuntime.h中,Nil被定义为什么都不做的 指针

请参阅此以获取更多信息-nil / Nil / NULL / NSNull


3

在某些情况下有所不同。

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

Nil等于空白,没有值。

根据编程环境,这可能会有很大差异。


1

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

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



0

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

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

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

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


0

这将帮助您了解nil,NIL和null之间的区别。

以下链接可能会以某种方式为您提供帮助:

http://nshipster.com/nil/

nil-> Objective-C对象的原义null值。

Nil-> Objective-C类的原义null值。

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

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


是否添加了新内容(现有答案未涵盖)?
Florian Koch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.