一、NULL
stddef.h文件
#undef NULL
#ifdef __cplusplus
#? if !defined(__MINGW32__) && !defined(_MSC_VER)
#? ? define NULL __null
#? else
#? ? define NULL 0
#? endif
#else
#? define NULL ((void*)0)
#endif
其中__cplusplus表示是不是C++代碼,所以對(duì)于普通的iOS開發(fā)者來(lái)說(shuō),通常NULL的定義就是:
# define NULL ((void*)0)
因此,NULL本質(zhì)上是:(void*)0
NULL表示C指針為空
char *string = NULL;
二、nil
objc.h文件
#ifndef nil
# if __has_feature(cxx_nullptr)
#? define nil nullptr
# else
#? define nil __DARWIN_NULL
# endif
#endif
其中__has_feature(cxx_nullptr)用于判斷C++中是否有nullptr特性,對(duì)于普通iOS開發(fā)者來(lái)說(shuō),nil的定義形式為:
# define nil __DARWIN_NULL
就是說(shuō)nil最終是__DARWIN_NULL的宏定義,__DARWIN_NULL是定義在_types.h中的宏,其定義形式如下:
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */
非C++代碼的__DARWIN_NULL最終定義形式如下
#define __DARWIN_NULL ((void *)0)
也就是說(shuō),nil本質(zhì)上是:(void *)0
用于表示指向Objective-C中對(duì)象的指針為空
NSString *string = nil;
id anyObject = nil;
三、Nil
objc.h文件
#ifndef Nil
# if __has_feature(cxx_nullptr)
#? define Nil nullptr
# else
#? define Nil __DARWIN_NULL
# endif
#endif
和上面講到的nil一樣,Nil本質(zhì)上也是:(void *)0
用于表示Objective-C類(Class)類型的變量值為空
Class anyClass = Nil;
四、NSNull
NSNull.h文件
@interface NSNull : NSObject
+ (NSNull *)null;
@end
3、用處及含義
從定義中可以看出,NSNull是一個(gè)Objective-C類,只不過(guò)這個(gè)類相當(dāng)特殊,因?yàn)樗硎镜氖强罩?,即什么都不存。它也只有一個(gè)單例方法+[NSUll null]。該類通常用于在集合對(duì)象中保存一個(gè)空的占位對(duì)象。
4、示例
我們通常初始化NSArray對(duì)象的形式如下:
NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zz",nil];
當(dāng)NSArray里遇到nil時(shí),就說(shuō)明這個(gè)數(shù)組對(duì)象的元素截止了,即NSArray只關(guān)注nil之前的對(duì)象,nil之后的對(duì)象會(huì)被拋棄。比如下面的寫法:
NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zz",nil,@"foogry"];
這是NSArray中只會(huì)保存wang和zz兩個(gè)字符串,foogry字符串會(huì)被拋棄。
這種情況,就可以使用NSNull實(shí)現(xiàn)
NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zz",[NSNull null],@"foogry"];
五、總結(jié)
從前面的介紹可以看出,不管是NULL、nil還是Nil,它們本質(zhì)上都是一樣的,都是(void *)0,只是寫法不同。這樣做的意義是為了區(qū)分不同的數(shù)據(jù)類型,比如你一看到用到了NULL就知道這是個(gè)C指針,看到nil就知道這是個(gè)Objective-C對(duì)象,看到Nil就知道這是個(gè)Class類型的數(shù)據(jù)。