我们来分别介绍一下这四种类型:

一、nil

我们给对象赋值时一般会使用object = nil,表示我想把这个对象释放掉;

或者对象由于某种原因,经过多次release,于是对象引用计数器为0了,系统将这块内存释放掉,这个时候这个对象为nil,我称它为“空对象”。(注意:我这里强调的是“空对象”,下面我会拿它和“值为空的对象”作对比!!!)

所以对于这种空对象,所有关于retain的操作都会引起程序崩溃,例如字典添加键值或数组添加新原素等,具体可参考如下代码:


二、NSNull

NSNull和nil的区别在于,nil是一个空对象,已经完全从内存中消失了,而如果我们想表达“我们需要有这样一个容器,但这个容器里什么也没有”的观念时,我们就用到NSNull,我称它为“值为空的对象”。如果你查阅开发文档你会发现NSNull这个类是继承NSObject,并且只有一个“+ (NSNull *) null;”类方法。这就说明NSNull对象拥有一个有效的内存地址,所以在程序中对它的任何引用都是不会导致程序崩溃的。参考代码如下:



三、Nil

nil和Nil在使用上是没有严格限定的,也就是说凡是使用nil的地方都可以用Nil来代替,反之亦然。只不过从编程人员的规约中我们约定俗成地将nil表示一个空对象,Nil表示一个空类。参考代码如下:


 

四、NULL

我们知道Object-C来源于C、支持于C,当然也有别于C。而NULL就是典型C语言的语法,它表示一个空指针,参考代码如下:

int *ponit = NULL;  

 

说法二

1.nil

指向一个对象的指针为空 在objc.h中的定义如下所示:




1


2


3


4


5


6


7




​#ifndef nil​


​# ​​​​if​​ ​​__has_feature(cxx_nullptr)​


​#   define nil nullptr​


​# ​​​​else​


​#   define nil __DARWIN_NULL​


​# endif​


​#endif​



在Objective-C中用于id类型的对象




1


2


3




​NSString *name = nil;​


​NSURL    *url  = nil;​


​id object      = nil;​



2.Nil

指向一个类的指针为空 定义如下:




1


2


3


4


5


6


7




​#ifndef Nil​


​# ​​​​if​​ ​​__has_feature(cxx_nullptr)​


​#   define Nil nullptr​


​# ​​​​else​


​#   define Nil __DARWIN_NULL​


​# endif​


​#endif​



在Objective-C中用于Class类型的对象




1


2




​Class aClass = Nil;​


​Clsss bClass = [NSURL ​​​​class​​​​];​



3.NULL

指向C类型的指针为空 在stddef.h中定义如下:




1


2


3


4


5


6


7


8


9


10


11




​#​​​​if​​ ​​defined(__need_NULL)​


​#undef NULL​


​#ifdef __cplusplus​


​#  ​​​​if​​ ​​!defined(__MINGW32__) && !defined(_MSC_VER)​


​#    define NULL __null​


​#  ​​​​else​


​#    define NULL ​​​​0​


​#  endif​


​#​​​​else​


​#  define NULL ((​​​​void​​​​*)​​​​0​​​​)​


​#endif​



多用于如下例子:




1


2


3




​int​​   ​​*pInt     = NULL;​


​char​​ ​​*chChar <span style=​​​​"white-space:pre"​​​​> </span>= NULL;​


​struct stStruct = NULL;​



4.NSNull

在Objective-C中是一个类,只是名字中有个Null,NSNull有 + (NSNull *)null; 单例方法,多用于集合(NSArray,NSDictionary)中值为空的对象




1


2


3


4


5


6


7


8


9




​NSArray *array = [NSArray arrayWithObjects:​


​[[NSObject alloc] init],​


​[NSNull ​​​​null​​​​],​


​@​​​​"aaa"​​​​,​


​nil,​


​[[NSObject alloc] init],​


​[[NSObject alloc] init], nil];​


 


​NSLog(@​​​​"%ld"​​​​, array.count); ​​​​// 输出 3,NSArray以nil结尾​





1


2


3


4


5


6


7




​NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:​


​@​​​​"Object0"​​​​, @​​​​"Key0"​​​​,​


​@​​​​"Object1"​​​​, @​​​​"Key1"​​​​,​


​nil,        @​​​​"Key-nil"​


​@​​​​"Object2"​​​​, @​​​​"Key2"​​​​,​


​nil];​


​NSLog(@​​​​"%@"​​​​, dictionary); ​​​​// 输出2个key-value,NSDictionary也是以nil结尾​





1


2


3




​NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];​


​[mutableDictionary setObject:nil forKey:@​​​​"Key-nil"​​​​]; ​​​​// 会引起Crash​


​[mutableDictionary setObject:[NSNull ​​​​null​​​​] forKey:@​​​​"Key-nil"​​​​]; ​​​​// 不会引起Crash​



所以在使用时,如下方法是比较安全的




1


2




​[mutableDictionary setObject:(nil == value ? [NSNull ​​​​null​​​​] : value)​


​forKey:@​​​​"Key"​​​​];​