標籤:http io ar os 使用 sp for on 問題
轉自:http://nshipster.cn/nil/
理解“不存在”的概念不僅僅是一個哲學的問題,也是一個實際的問題。我們是有形宇宙的居民,而原因在於邏輯宇宙的存在不確定性。作為一個邏輯系統的物理體現,電腦面臨一個棘手的問題,就是如何用存在表達不存在.
在Objective-C中,有幾個不同種類的不存在。這樣做的原因要追溯到一個頻繁提及的NSHipster,講解Objective-C如何在C的程式範例以及由Smalltalk啟發的物件導向的範例中架起橋樑的。
C用0
來作為不存在的原始值,而NULL
作為指標(這在指標環境中相當於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
最顯著的行為是,它雖然為零,仍然可以有訊息發送給它。
在其他的語言中,比如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]
用來表示零值的單獨的對象
Objective-C 中nil/Nil/NULL/NSNull