天天看點

Objective-C 中的 instancetype 和 id 關鍵字

1. 什麼是 instancetype

instancetype 是 clang 3.5 開始,clang 提供的一個關鍵字,表示某個方法傳回的未知類型的 Objective-C 對象。我們都知道未知類型的的對象可以用 id 關鍵字表示,那為什麼還會再有一個 instancetype 呢?

2. 關聯傳回類型(related result types)

根據 Cocoa 的命名規則,滿足下述規則:

  1. 類方法中,以

    alloc

    new

    開頭
  2. 執行個體方法中,以

    autorelease

    init

    retain

    self

    開頭

的方法會傳回一個方法所在類的類型的對象,這些方法就被稱為是 關聯傳回類型 的方法。換句話說,這些方法的傳回結果以方法所在的類為類型。比如:

@interface NSObject
+ (id)alloc;
- (id)init;
@end

@interface NSArray : NSObject
@end
           

當我們使用如下方式初始化

NSArray

時:

NSArray *array = [[NSArray alloc] init];
           

按照 Cocoa 的命名規則,語句

[NSArray alloc]

的類型就是

NSArray*

。因為

alloc

的傳回類型屬于關聯傳回類型。同樣,

[[NSArray alloc] init]

的傳回結果也是

NSArray*

3. instancetype 作用

3.1 作用

如果一個不是關聯傳回類型的方法,如下:

@interface NSArray
+ (id)constructAnArray;
@end
           

當我們使用如下方式初始化 NSArray 時:

根據 Cocoa 的方法命名規範,得到的傳回類型就和方法聲明的傳回類型一樣,是

id

。但是如果使用

instancetype

作為傳回類型,如下:

@interface NSArray
+ (instancetype)constructAnArray;
@end
           

當使用相同方式初始化 NSArray 時:

得到的傳回類型和方法所在類的類型相同,是

NSArray*

!

總結一下,

instancetype

的作用,就是使那些非關聯傳回類型的方法傳回所在類的類型!

3.2 好處

能夠确定對象的類型,能夠幫助編譯器更好的為我們定位代碼書寫問題,比如:

[[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; //  "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"

[[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error)
           

上例中第一行代碼,由于

[[NSArray alloc] init]

的結果是

NSArray*

,這樣編譯器就能夠根據傳回的資料類型檢測出

NSArray

是否實作

mediaPlaybackAllowsAirPlay

方法。有利于開發者在編譯階段發現錯誤。

第二行代碼,由于

array

不屬于關聯傳回類型方法,

[NSArray array]

傳回的是

id

類型,編譯器不知道

id

類型的對象是否實作了

mediaPlaybackAllowsAirPlay

方法,也就不能夠替開發者及時發現錯誤。

4. instancetype 和 id 的異同

  • 相同點
    都可以作為方法的傳回類型。
               
  • 不同點
    1. instancetype

      可以傳回和方法所在類相同類型的對象,

      id

      隻能傳回未知類型的對象;
    2. instancetype

      隻能作為傳回值,不能像

      id

      那樣作為參數,比如下面的寫法:
//err,expected a type
- (void)setValue:(instancetype)value
{
    //do something
}
           

就是錯的,應該寫成:

- (void)setValue:(id)value
{
    //do something
}
           

原文出處: Objective-C中的instancetype和id關鍵字

英文原文連結:

1. http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-features

2. http://nshipster.com/instancetype/