Objective-C 基礎(chǔ)小Tip
instancetype 關(guān)鍵字祥得,它可以表示一個(gè)方法的相關(guān)返回類(lèi)型靠胜。例如:
@interface Person
+ (instancetype)personWithName:(NSString *)name;
@end
instancetype
與id
不一樣,instancetype
只能在方法聲明中作為返回類(lèi)型使用拳喻。
使用 instancetype
燕耿,編譯器將正確的推斷出 +personWithName:
是 Person
的一個(gè)實(shí)例径缅。
NSNull / nil / NULL
C 用 0 來(lái)作為 不存在 的原始值掺栅,而 NULL 作為指針(這在指針環(huán)境中相當(dāng)于0)。
Objective-C 在 C 的表達(dá) 不存在 的基礎(chǔ)上增加了 nil纳猪。nil 是一個(gè)指向不存在的 對(duì)象 指針氧卧。雖然它在語(yǔ)義上與 NULL 不同,但它們?cè)诩夹g(shù)上是相等的氏堤。
在框架層面沙绝,F(xiàn)oundation 定義了 NSNull,即一個(gè)類(lèi)方法 +null,它返回一個(gè)單獨(dú)的 NSNull 對(duì)象闪檬。NSNull 與 nil 以及 NULL 不同星著,因?yàn)樗且粋€(gè)實(shí)際的對(duì)象,而不是一個(gè)零值粗悯。
另外虚循,在 Foundation/NSObjCRuntime.h 中,Nil 被定義為指向零的 類(lèi) 指針为黎。這個(gè)nil的鮮為人知的大寫(xiě)的表兄并不常常出現(xiàn)邮丰,但它至少值得注意。
關(guān)于 nil 的一些事
剛被 分配 的 NSObject 的內(nèi)容被設(shè)置為0铭乾。也就是說(shuō)那個(gè)對(duì)象所有的指向其他對(duì)象的指針都從 nil 開(kāi)始剪廉,所以在 init 方法中設(shè)置 self.(association) = nil 之類(lèi)的表達(dá)是沒(méi)有必要的。
也許 nil 最顯著的行為是炕檩,它雖然為零斗蒋,仍然可以有消息發(fā)送給它。
在其他的語(yǔ)言中笛质,比如 C++泉沾,這樣做會(huì)使你的程序崩潰,但在 Objective-C 中妇押,在 nil 上調(diào)用方法返回一個(gè)零值跷究。這大大的簡(jiǎn)化了表達(dá),因?yàn)樗苊饬嗽谑褂?nil 之前對(duì)它的檢查:
// 舉個(gè)例子敲霍,這個(gè)表達(dá)...
if (name != nil && [name isEqualToString:@"Steve"]) { ... }
// …可以被簡(jiǎn)化為:
if ([name isEqualToString:@"steve"]) { ... }
了解 nil 如何在 Objective-C 中工作可以讓你將這個(gè)便利變成一個(gè)功能俊马,而不是潛伏在你的應(yīng)用中的 bug。要確保避免當(dāng) nil 值不需要的情況肩杈,要么通過(guò)檢查或者提前返回來(lái)安靜的失敗柴我,或者通過(guò)增加一個(gè) NSParameterAssert 來(lái)拋出異常。
標(biāo)志 | 值 | 含義 |
---|---|---|
NULL | (void *)0 | C指針的字面零值 |
nil | (id)0 | Objective-C對(duì)象的字面零值 |
Nil | (Class)0 | Objective-C類(lèi)的字面零值 |
NSNull | [NSNull null] | 用來(lái)表示零值的單獨(dú)的對(duì)象 |
自定義索引下標(biāo)
為你的類(lèi)增加自定義索引下標(biāo)扩然,你只需要聲明和實(shí)現(xiàn)下列方法:
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
自定義鍵位下標(biāo)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
同樣的艘儒,你也可以通過(guò)聲明和實(shí)現(xiàn)以下方法增加自定義鍵位下標(biāo)到你的類(lèi):
- (id)objectForKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;