iOS大神留步,你確定你會使用id和instancetype?

baitiefu 7年前發布 | 6K 次閱讀 iOS開發 移動開發

寫了那么多代碼,懂了那么多道理,可是我就問你一句:id和instancetype的使用你懂了嗎?

1.
- (instancetype)init{
    self = [super init ];
    if (self) {

    }
    return self;
}

2.
- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:(CGRect)frame];
    if (self) {

    }
    return self;
}

上述的兩處代碼我們經常在使用,但是有多少人知道這里的instancetype返回值表示什么意思?這里為什么用的instancetype而不用id?這里用id又會怎么樣?

要搞懂id 和instancetype的異同 首先要弄懂iOS中兩個概念:關聯返回類型/非關聯返回類型

根據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*。
到這里還沒看懂的[捂臉][捂臉][捂臉],沒關系我也是看了兩遍才看懂什么意思,多看幾遍就懂了。

既然關聯返回類型是類方法中以alloc或new開頭 實例方法中以autorelease,init,retain或self開頭的,那么非關聯返回類型肯定就是相反的定義了。舉個例子吧

@interface NSArray  
+ (id)constructAnArray;  
@end  
根據Cocoa的命名規則,這個肯定就不是關聯返回類型,那一定就是非關聯返回類型了
當我們使用如下方式初始化NSArray時:[NSArray constructAnArray]; 
根據Cocoa的方法命名規范,得到的返回類型就和方法聲明的返回類型一樣,是id。(重點:因為它不符合關聯返回類型命名規范)

對上面的返回類型我們做一點修改
但是如果使用instancetype作為返回類型,如下:
@interface NSArray  
+ (instancetype)constructAnArray;  
@end  
我們使用instancetype做返回類型
當使用相同方式初始化NSArray時:[NSArray constructAnArray]; 得到的返回類型和方法所在類的類型相同,是NSArray*

到這里就已經可以對比出來id和instancetype的異同了

總結一下,instancetype的作用,就是使那些非關聯返回類型的方法返回所在類的類型!

為什么要使用instancetype?

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

[[[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方法,也就不能夠替開發者及時發現錯誤。

instancetype和id的異同

1、相同點

都可以作為方法的返回類型

2、不同點

①instancetype可以返回和方法所在類相同類型的對象,id只能返回未知類型的對象;

②instancetype只能作為返回值,不能像id那樣作為參數,比如下面的寫法:

//err,expected a type  
- (void)setValue:(instancetype)value  
{  
    //do something  
}  

就是錯的,應該寫成:
- (void)setValue:(id)value  
{  
    //do something  
}

 

來自:http://www.jianshu.com/p/37c0060fbe27

 

 本文由用戶 baitiefu 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!