天天看點

nil-Nil-NULL-NSNull差別Nil關于 nil 的一些事NSNull:有作沒有

  • nil: 一般指派給空對象
  • Nil: Objective-C類的字面零值
  • NULL: 一般指派給nil之外的其他空值。如SEL等;
  • NSNull: NSNull隻有一個方法:+ (NSNull *) null;

      [NSNull null]用來在NSArray和NSDictionary中加入非nil(表示清單結束)的空值.

當向nil發送消息時,傳回NO,不會有異常,程式将繼續執行下去;

而向NSNull的對象發送消息時會收到異常。

C用0來作為不存在的原始值,而NULL作為指針(這在指針環境中相當于0)。

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

在架構層面,Foundation定義了NSNull,即一個類方法+null,它傳回一個單獨的NSNull對象。NSNull與nil以及NULL不同,因為它是一個實際的對象,而不是一個零值。

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

Nil

定義一個空的類

Class someClass = Nil;
Class anotherClass = [NSString class];
           

關于 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:有作沒有

集合對象無法包含nil作為其具體值,如NSArray、NSSet和NSDictionary。相應地,nil值用一個特定的對象NSNull來表示。NSNull提供了一個單一執行個體用于表示對象屬性中的的nil值。預設的實作方法中,dictionaryWithValuesForKeys:和setValuesForKeysWithDictionary:自動地将NSNull和nil互相轉換,是以您的對象不需要進行NSNull的測試操作。

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對象被設計來跟NULL空指針關聯的。他們的差別就是

nil是一個對象

,而

NULL隻是一個值

。而且我們對于nil調用方法,不會産生crash或者抛出異常。

這個技術被framework通過多種不同的方式使用。最主要的就是我們現在在調用方法之前根本無須去檢查這個對象是否是nil。假如我們調了nil對象的一個有傳回值的方法,那麼我們會得到一個nil傳回值。

我們可以通過nil對象讓我們的dealloc函數實作看上去更帥一點:

- (void) dealloc

{

self.caption = nil;

self.photographer = nil;

[super dealloc];

}

繼續閱讀