理解“不存在”的概念不僅僅是一個哲學的問題,也是一個實際的問題涕蚤。我們是 有形 宇宙的居民,而原因在于邏輯宇宙的存在不確定性的诵。作為一個邏輯系統(tǒng)的物理體現万栅,電腦面臨一個棘手的問題,就是如何用 存在 表達 不存在 .
在 Objective-C 中西疤,有幾個不同種類的 不存在烦粒。這樣做的原因要追溯到一個頻繁提及的NSHipster,講解 Objective-C 如何在 C 的程序范例以及由 Smalltalk 啟發(fā)的面向對象的范例中架起橋梁的代赁。
C 用 0
來作為 不存在 的原始值扰她,而 NULL
作為指針(這在指針環(huán)境中相當于0
)。
Objective-C 在 C 的表達 不存在 的基礎上增加了 nil
芭碍。nil
是一個指向不存在的 對象 指針徒役。雖然它在語義上與 NULL
不同,但它們在技術上是相等的窖壕。
在框架層面忧勿,Foundation 定義了 NSNull
,即一個類方法 +null
瞻讽,它返回一個單獨的 NSNull
對象鸳吸。NSNull
與 nil
以及 NULL
不同,因為它是一個實際的對象速勇,而不是一個零值晌砾。
另外,在 Foundation/NSObjCRuntime.h 中烦磁,Nil
被定義為指向零的 類 指針养匈。這個nil
的鮮為人知的大寫的表兄并不常常出現,但它至少值得注意个初。
關于 nil
的一些事
剛被 分配
的 NSObject
的內容被設置為0
乖寒。也就是說那個對象所有的指向其他對象的指針都從 nil
開始,所以在 init
方法中設置 self.(association) = nil
之類的表達是沒有必要的院溺。
也許 nil
最顯著的行為是楣嘁,它雖然為零,仍然可以有消息發(fā)送給它珍逸。
在其他的語言中逐虚,比如 C++,這樣做會使你的程序崩潰谆膳,但在 Objective-C 中叭爱,在 nil
上調用方法返回一個零值。這大大的簡化了表達漱病,因為它避免了在使用 nil
之前對它的檢查:
// 舉個例子买雾,這個表達...
if (name != nil && [name isEqualToString:@"Steve"]) { ... }
// …可以被簡化為:
if ([name isEqualToString:@"steve"]) { ... }
了解 nil
如何在 Objective-C 中工作可以讓你將這個便利變成一個功能把曼,而不是潛伏在你的應用中的 bug。要確保避免當 nil
值不需要的情況漓穿,要么通過檢查或者提前返回來安靜的失敗嗤军,或者通過增加一個 NSParameter<wbr style="box-sizing: border-box;">Assert
來拋出異常。
NSNull
:有作沒有
NSNull
在 Foundation 和其它框架中被廣泛的使用晃危,以解決如 NSArray
和 NSDictionary
之類的集合不能有 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] | 用來表示零值的單獨的對象 |