nil / Nil / NULL / NSNull 全解
???理解“不存在”的概念不僅僅是一個哲學(xué)的問題,也是一個實際的問題饥伊。我們是有形宇宙的居民殖属,而原因在于邏輯宇宙的存在不確定性。作為一個邏輯系統(tǒng)的物理體現(xiàn)潘悼,電腦面臨一個棘手的問題齐唆,就是如何用存在表達不存在嗤栓。
???在Objective-C中,有幾個不同種類的不存在箍邮。這樣做的原因要追溯到一個頻繁提及的NSHipster茉帅,講解Objective-C如何在C的程序范例以及由Smalltalk啟發(fā)的面向?qū)ο蟮姆独屑芷饦蛄旱摹?/p>
???C用0來作為不存在的原始值,而NULL作為指針(這在指針環(huán)境中相當于0)锭弊。 Objective-C在C的表達不存在的基礎(chǔ)上增加了nil担敌。nil是一個指向不存在的對象指針。雖然它在語義上與NULL不同廷蓉,但它們在技術(shù)上是相等的全封。
???在框架層面,F(xiàn)oundation定義了NSNull桃犬,即一個類方法+null刹悴,它返回一個單獨的NSNull對象。NSNull與nil以及NULL不同攒暇,因為它是一個實際的對象土匀,而不是一個零值。另外形用,在Foundation/NSObjCRuntime.h中就轧,Nil被定義為指向零的類指針。這個nil的鮮為人知的大寫的表兄并不常常出現(xiàn)田度,但它至少值得注意妒御。
關(guān)于 nil 的一些事
???剛被分配的NSObject的內(nèi)容被設(shè)置為0。也就是說那個對象所有的指向其他對象的指針都從nil開始镇饺,所以在init方法中設(shè)置self乎莉。(association) = nil之類的表達是沒有必要的。也許nil最顯著的行為是,它雖然為零惋啃,仍然可以有消息發(fā)送給它哼鬓。
???在其他的語言中,比如C++边灭,這樣做會使你的程序崩潰异希,但在Objective-C中,在nil上調(diào)用方法返回一個零值绒瘦。這大大的簡化了表達称簿,因為它避免了在使用nil之前對它的檢查:
// 舉個例子,這個表達椭坚。予跌。搏色。
if (name != nil && [name isEqualToString:@"Steve"]) {
善茎。。频轿。
}
// …可以被簡化為:
if ([name isEqualToString:@"steve"]) {
垂涯。。航邢。
}
???了解nil如何在Objective-C中工作可以讓你將這個便利變成一個功能耕赘,而不是潛伏在你的應(yīng)用中的bug。要確保避免當nil值不需要的情況膳殷,要么通過檢查或者提前返回來安靜的失敗操骡,或者通過增加一個NSParameterAssert來拋出異常。
NSNull:有作沒有
???NSNull在Foundation和其它框架中被廣泛的使用赚窃,以解決如NSArray和NSDictionary之類的集合不能有nil值的缺陷册招。你可以將NSNull理解為有效的將NULL或者nil值封裝boxing,以達到在集合中使用它們的目的:
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
//Sets value of NSNull singleton for "someKey"
mutableDictionary[@"someKey"] = [NSNull null];
//@[@"someKey"]
NSLog(@"Keys: %@", [mutableDictionary allKeys]);
對比
???總的來說勒极,這里的四個表達沒有的值是每個Objective-C程序員都應(yīng)該知道的是掰。
標志 | 值 | 含義 | 用途 |
---|---|---|---|
NULL | (void *)0 | C指針的字面零值 “空指針” | int *ponit = NULL; 它表示一個空指針 |
nil | (id)0 | Objective-C對象的字面零值 “空對象” | object = nil,表示我想把這個對象釋放掉 |
Nil | (Class)0 | Objective-C類的字面零值 “空類" | 用法和nil一樣辱匿,一般使用nil寫法 |
NSNull | [NSNull null] | 用來表示零值的單獨的對象 “值為空的對象” | NSNull繼承自NSObject键痛,NSNull對象擁有一個有效的內(nèi)存地址,可以作為空值容器匾七。不能接受消息 |