標籤:
這些年來,Objective-C在不斷的發展和進化。儘管最核心的概念和實踐都是一直未變的,它還是在很多方面發生了巨大的改變,並取得了巨大的進步。這些改變提高了諸如型別安全,記憶體管理,效能等方方面面的特性,讓編寫Objective-C變得更加容易。為了讓你現在和未來的代碼變得更加健壯,可靠和更加有彈性,適應這些改變將是十分重要的事情。 Xcode為你準備了一個適應這些結構化改變的工具。但是在你使用它之前,你會想這些改變會對你的代碼做什麼改變,並且為什麼做這些改變。這篇文檔重點講述了要發生在你的代碼上的最為重要和有用的改變。instancetype 使用instancetype關鍵字作為類初始化方法的傳回值類型。這些方法包括alloc,init和類Factory 方法。 在你的OC代碼裡合適的地方使用instancetype而不是id著實提高了型別安全。例如,思考下面的代碼 :
1 @interface MyObject : NSObject 2 + (instancetype)factoryMethodA; 3 + (id)factoryMethodB; 4 @end 5 6 @implementation MyObject 7 + (instancetype)factoryMethodA { return [[[self class] alloc] init]; } 8 + (id)factoryMethodB { return [[[self class] alloc] init]; } 9 @end10 11 void doSomething() {12 NSUInteger x, y;13 14 x = [[MyObject factoryMethodA] count]; // Return type of +factoryMethodA is taken to be "MyObject *"15 y = [[MyObject factoryMethodB] count]; // Return type of +factoryMethodB is "id"16 }
因為+factoryMethodA的傳回值類型是instancetype, 所以傳遞訊息所表達的是MyObject *類型。而MyObject並沒有-count這個方法,所以編譯器會給出下面的警告: main.m: ’MyObject’ may not respond to ‘count’
然而,因為+factoryMethodB的傳回值類型是id類型,編譯器將不會給出相應的警告。因為id類型的對象可以是任何一種類,而同時,-count方法可能會存在與某個類中,所以,對於編譯器來說,+factoryMethodB的傳回值是由可能去實現-count這個方法的。 為了確保instancetypeFactory 方法擁有正確的子類表現,當在初始化類執行個體的時候請確保使用[self class]而不是[類名 class]。這樣,才能確保編譯器正確的推斷出子類類型。例如,如果對上面的代碼中MyObject的子類中做出下面的操作,會發生什麼呢?
1 @interface MyObjectSubclass : MyObjet2 @end3 4 void doSomethingElse() {5 NSString *aString = [MyObjectSubclass factoryMethodA];6 }
編譯器會給出以下警告:
1 main.m: Incompatible pointer types initializing ’NSString *’ with an expression of type ’MyObjectSubclass *’
Adopting Modern Objective-C 譯文