轉自:http://nshipster.cn/nil/html
理解「不存在」的概念不單單是一個哲學的問題,也是一個實際的問題。咱們是有形宇宙的居民,而緣由在於邏輯宇宙的存在不肯定性。做爲一個邏輯系統的物理體現,電腦面臨一個棘手的問題,就是如何用存在表達不存在.git
在Objective-C中,有幾個不一樣種類的不存在。這樣作的緣由要追溯到一個頻繁說起的NSHipster,講解Objective-C如何在C的程序範例以及由Smalltalk啓發的面向對象的範例中架起橋樑的。程序員
C用0
來做爲不存在的原始值,而NULL
做爲指針(這在指針環境中至關於0
)。github
Objective-C在C的表達不存在的基礎上增長了nil
。nil
是一個指向不存在的對象指針。雖然它在語義上與NULL
不一樣,但它們在技術上是相等的。app
在框架層面,Foundation定義了NSNull
,即一個類方法+null
,它返回一個單獨的NSNull
對象。NSNull
與nil
以及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和其它框架中被普遍的使用,以解決如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] 用來表示零值的單獨的對象