NULL數組
NULL 定義在 usr/include/sys/_types/_null.h 文件裏:.net
#ifndef NULL指針
#define NULL __DARWIN_NULL對象
#endif /* NULL */get
其中 __DARWIN_NULL 的定義在 usr/include/sys/__types.h 文件裏,以下:編譯器
#ifdef __cplusplusit
# ifdef __GNUG__io
# define __DARWIN_NULL __null編譯
# else /* ! __GNUG__ */table
# 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 的取值,而後定了其餘環境下 __DARWIN_NULL 的值,所以在 Objective-C 中 NULL 的最終定義爲:
#define NULL ((void*)0)
即 NULL 本質上是:(void*)0。
使用慣例:NULL 通常用於表示 C 指針空值,例如:
int *pointerToInt = NULL;
char *pointerToChar = NULL;
struct TreeNode *rootNode = NULL;
nil
nil 定義在 usr/include/objc/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 特性,若是有,nil 定義爲 nullptr,不然 nil 定義爲 __DARWIN_NULL,因此在 Objective-C 中 nil 的最終定義爲:
#define nil ((void*)0)
也就是說,nil 本質上也是:(void *)0,與 NULL 一致。
使用慣例:nil 用於表示指向 Objective-C 對象(id 類型的對象,或者使用 @interface 聲明的 OC 對象)的指針爲空,例如:
NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;
if (anotherObject == nil) // do something
Nil
Nil 定義在 usr/include/objc/objc.h 文件裏:
#ifndef Nil
# if __has_feature(cxx_nullptr)
# define Nil nullptr
# else
# define Nil __DARWIN_NULL
# endif
#endif
與上述 nil 一致,Nil 本質上也是:(void *)0。
使用慣例:Nil 用於表示指向 Objective-C 類(Class)類型的指針爲空,例如:
Class someClass = Nil;
Class anotherClass = [NSString class];
NSNull
NSNull 定義在 NSNull.h 文件裏:
#import
NS_ASSUME_NONNULL_BEGIN
@interface NSNull : NSObject
+ (NSNull *)null;
NS_ASSUME_NONNULL_END
從上述定義中,咱們可知 NSNull 是一個 Objective-C 對象,是一個用於表示空值的類,並且它只有一個單例方法:+[NSNull null],通常用於在集合對象中保存一個空的佔位對象。
使用慣例:在 Foundation 集合對象(NSArray、NSDictionary、NSSet 等)中, nil 一般被用於表示集合對象結束的標誌,所以沒法用 nil 來存儲一個空值,因此通常用 [NSNull null] 空對象來存儲。另外,在 NSDictionary 的 -objectForKey: 方法中,若是當前字典中 key 對應的值不存在時,該方法會返回 nil,代表當前 key 在字典中未添加,可是若是咱們想明確表示某一 key 已經在字典中添加,可是它沒有值,這時候就能夠用 [NSNull null] 來賦值表示。
// 當 NSArray 裏遇到 nil 時,就說明這個數組對象的元素截止了,即 NSArray 只關注 nil 以前的對象,nil 以後的對象會被拋棄。
NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil];
// 錯誤的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:nil forKey:@"someKey"];
// 正確的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"someKey"];
NIL 或 NSNil
Objective-C 中不存在這兩個符號!!!
總結
從上述分析咱們可知,無論是 NULL、nil 仍是 Nil,它們本質上是同樣的,都是 (void *)0,只是寫法不一樣。這樣作的意義是爲了區分不一樣的數據類型,雖然它們值相同,但咱們須要理解它們之間的字面意義並用於不一樣場景,讓代碼更加明確,增長可讀性。
標誌 | 值 | 含義 |
---|---|---|
NULL | (void *)0 | C 指針的字面空值 |
nil | (id)0 | Objective-C 對象的字面空值 |
Nil | (Class)0 | Objective-C 類的字面空值 |
NSNull | [NSNull null] | 用來表示空值的 Objective-C 對象 |