Objective-C 中nil/Nil/NULL/NSNull

轉自:http://nshipster.cn/nil/html

理解「不存在」的概念不單單是一個哲學的問題,也是一個實際的問題。咱們是有形宇宙的居民,而緣由在於邏輯宇宙的存在不肯定性。做爲一個邏輯系統的物理體現,電腦面臨一個棘手的問題,就是如何用存在表達不存在.git

在Objective-C中,有幾個不一樣種類的不存在。這樣作的緣由要追溯到一個頻繁說起的NSHipster,講解Objective-C如何在C的程序範例以及由Smalltalk啓發的面向對象的範例中架起橋樑的。程序員

C用0來做爲不存在的原始值,而NULL做爲指針(這在指針環境中至關於0)。github

Objective-C在C的表達不存在的基礎上增長了nilnil是一個指向不存在的對象指針。雖然它在語義上與NULL不一樣,但它們在技術上是相等的。app

在框架層面,Foundation定義了NSNull,即一個類方法+null,它返回一個單獨的NSNull對象。NSNullnil以及NULL不一樣,由於它是一個實際的對象,而不是一個零值。框架

另外,在Foundation/NSObjCRuntime.h中,Nil被定義爲指向零的指針。這個nil的不爲人知的大寫的表兄並不經常出現,但它至少值得注意。指針

關於 nil 的一些事

剛被分配NSObject內容被設置爲0。也就是說那個對象全部的指向其餘對象的指針都從nil開始,因此在init方法中設置self.(association) = nil之類的表達是沒有必要的。code

也許nil最顯著的行爲是,它雖然爲零,仍然能夠有消息發送給它。htm

在其餘的語言中,好比C++,這樣作會使你的程序崩潰,但在Objective-C中,在nil上調用方法返回一個零值。這大大的簡化了表達,由於它避免了在使用nil以前對它的檢查:對象

// 舉個例子,這個表達...
if (name != nil && [name isEqualToString:@"Steve"]) { ... }

// …能夠被簡化爲:
if ([name isEqualToString:@"steve"]) { ... }

瞭解nil如何在Objective-C中工做可讓你將這個便利變成一個功能,而不是潛伏在你的應用中的bug。要確保避免當nil值不須要的狀況,要麼經過檢查或者提早返回來安靜的失敗,或者經過增長一個NSParameterAssert來拋出異常。

NSNull:有做沒有

NSNull在Foundation和其它框架中被普遍的使用,以解決如NSArrayNSDictionary之類的集合不能有nil值的缺陷。你能夠將NSNull理解爲有效的將NULL或者nil值封裝boxing,以達到在集合中使用它們的目的:

NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
mutableDictionary[@"someKey"] = [NSNull null]; // Sets value of NSNull singleton for `someKey`
NSLog(@"Keys: %@", [mutableDictionary allKeys]); // @[@"someKey"]

總的來講,這裏的四個表達沒有的值是每一個Objective-C程序員都應該知道的:

NULL
(void *)0
C指針的字面零值

nil
(id)0
Objective-C對象的字面零值

Nil
(Class)0
Objective-C類的字面零值

NSNull
[NSNull null] 用來表示零值的單獨的對象

相關文章
相關標籤/搜索