Objective-C 基礎小Tip
instancetype 關鍵字,它可以表示一個方法的相關返回類型。例如:
@interface Person
+ (instancetype)personWithName:(NSString *)name;
@end
instancetype
與id
不一樣,instancetype
只能在方法聲明中作為返回類型使用。
使用 instancetype
,編譯器將正確的推斷出 +personWithName:
是 Person
的一個實例。
NSNull / nil / NULL
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 來拋出異常。
標志 | 值 | 含義 |
---|---|---|
NULL | (void *)0 | C指針的字面零值 |
nil | (id)0 | Objective-C對象的字面零值 |
Nil | (Class)0 | Objective-C類的字面零值 |
NSNull | [NSNull null] | 用來表示零值的單獨的對象 |
自定義索引下標
為你的類增加自定義索引下標,你只需要聲明和實現下列方法:
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
自定義鍵位下標
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
同樣的,你也可以通過聲明和實現以下方法增加自定義鍵位下標到你的類:
- (id)objectForKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;