日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

[iOS]用instancetype代替id作返回類型有什么好

系統 2901 0

蘋果在iOS 8中全面使用instancetype代替id

Steven Fisher:只要一個類返回自身的實例,用instancetype就有好處。

      
        
          @interface 
          
            Foo:
            
              NSObject 
              
                - 
                
                  (
                  
                    id
                    
                      )
                      
                        initWithBar
                        
                          :(
                          
                            NSInteger
                            
                              )
                              
                                bar
                                
                                  ; 
                                  
                                    // initializer 
                                    
                                      + 
                                      
                                        (
                                        
                                          id
                                          
                                            )
                                            
                                              fooWithBar
                                              
                                                :(
                                                
                                                  NSInteger
                                                  
                                                    )
                                                    
                                                      bar
                                                      
                                                        ; 
                                                        
                                                          // convenience constructor 
                                                          
                                                            @end 
                                                          
                                                        
                                                      
                                                    
                                                  
                                                
                                              
                                            
                                          
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

對于簡易構造函數(convenience constructor),應該總是用instancetype。編譯器不會自動將id轉化為instancetype。id是通用對象,但如果你用instancetype,編譯器就知道方法返回什么類型的對象。

這個問題可不只有學術意義,比如,[[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData]在Mac OS X(只在該OS版本)中會報錯“Multiple methods named 'writeData:' found with mismatched result, parameter type or attributes.”原因是NSFileHandle和NSURLHandle都提供writeData:方法。由于[NSFileHandle fileHandleWithStandardOutput] 返回的類型是id,編譯器并不確定請求了哪個類的writeData:方法。

你可以用

      
        
          [(
          
            NSFileHandle 
            
              *
              
                )[
                
                  NSFileHandle 
                  
                    fileHandleWithStandardOutput
                    
                      ] 
                      
                        writeData
                        
                          :
                          
                            formattedData
                            
                              ]; 
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

      
        
          NSFileHandle 
          
            *
            
              fileHandle 
              
                = 
                
                  [
                  
                    NSFileHandle 
                    
                      fileHandleWithStandardOutput
                      
                        ]; 
                        
                          [
                          
                            fileHandle 
                            
                              writeData
                              
                                :
                                
                                  formattedData
                                  
                                    ]; 
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

來繞過。

當然,更好的方法是聲明fileHandleWithStandardOutput的返回類型為instancetype。(注意:這段樣例代碼在iOS中并不會報錯,因為iOS中只有NSFileHandle提供writeData:方法。但length等方法則會,UILayoutSupport會返回CGFloat,而NSString則會返回NSUInteger)

initializer的情況更復雜,當你輸入

      
        
          - 
          
            (
            
              id
              
                )
                
                  initWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar 
                        
                      
                    
                  
                
              
            
          
        
      
    

編譯器會假設你輸入了

      
        
          - 
          
            (
            
              instancetype
              
                )
                
                  initWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar 
                        
                      
                    
                  
                
              
            
          
        
      
    

對于ARC而言,這是必須的。 Clang Language Extensions 的相關結果類型(Related result types)也講到了這一點。也許別人會據此告訴你不必使用instancetype,但我建議你用它。下面解釋我為什么如此建議。

使用instancetype有三點好處:

1、明確性。代碼只做你讓它做的事,而不是其他。

2、程式化。你會養成好習慣,這些習慣在某些時候會很有用,而且肯定有用武之地。

3、一致性。讓代碼可讀性更好。

明確性

用instancetype代替id作為返回值的確沒有 技術上的好處 。但這是因為編譯器自動將id轉化成了instancetype。你以為init返回的值類型是id,其實編譯器返回了instancetype。

這兩行代碼對于編譯器來說是 一樣 的:

      
        
          - 
          
            (
            
              id
              
                )
                
                  initWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar
                          
                            ; 
                            
                              - 
                              
                                (
                                
                                  instancetype
                                  
                                    )
                                    
                                      initWithBar:
                                      
                                        (
                                        
                                          NSInteger
                                          
                                            )
                                            
                                              bar
                                              
                                                ; 
                                              
                                            
                                          
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

但在你眼里,這兩行代碼卻不同。你不該學著忽視它。

模式化

在使用init等方法時的確沒有區別,但在定義簡易構造函數時就有區別了。

這兩行代碼并不等價:

      
        
          + 
          
            (
            
              id
              
                )
                
                  fooWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar
                          
                            ; 
                            
                              + 
                              
                                (
                                
                                  instancetype
                                  
                                    )
                                    
                                      fooWithBar:
                                      
                                        (
                                        
                                          NSInteger
                                          
                                            )
                                            
                                              bar
                                              
                                                ; 
                                              
                                            
                                          
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

如果用instancetype作為函數的返回類型,就不會出錯。

一致性:

最后,想象把所有東西放到一起時的情景:你想要一個init方法和一個簡易構造函數。

如果你用id來作為init函數的返回類型,最終代碼如下:

      
        
          - 
          
            (
            
              id
              
                )
                
                  initWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar
                          
                            ; 
                            
                              + 
                              
                                (
                                
                                  instancetype
                                  
                                    )
                                    
                                      fooWithBar:
                                      
                                        (
                                        
                                          NSInteger
                                          
                                            )
                                            
                                              bar
                                              
                                                ; 
                                              
                                            
                                          
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

但如果你用instancetype,代碼如下:

      
        
          - 
          
            (
            
              instancetype
              
                )
                
                  initWithBar:
                  
                    (
                    
                      NSInteger
                      
                        )
                        
                          bar
                          
                            ; 
                            
                              + 
                              
                                (
                                
                                  instancetype
                                  
                                    )
                                    
                                      fooWithBar:
                                      
                                        (
                                        
                                          NSInteger
                                          
                                            )
                                            
                                              bar
                                              
                                                ; 
                                              
                                            
                                          
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          
        
      
    

代碼更加一致,可讀性更強。它們返回相同的東西,這一點一目了然。

結論

除非你有意為舊編譯器寫代碼,不然你在合適的時候都應該用instancetype。

在寫一條返回id的消息前,問自己:這個類返回實例嗎?如果返回,用instancetype。

肯定有需要返回id的時候,但你用instancetype的頻率應該會更高。

本答案摘自:http://zhuanlan.zhihu.com/Foundation/19569459

原帖: objective c - Would it be beneficial to begin using instancetype instead of id?

注意:我也是剛入門而已,如果翻譯的術語與通行術語不一致,敬請告知;如果選取的翻譯內容有誤或過時,敬請告知,謝謝。

[iOS]用instancetype代替id作返回類型有什么好處?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 南涧| 长葛市| 鹿邑县| 锦州市| 喀喇| 沾益县| 托里县| 建宁县| 赤峰市| 建水县| 五峰| 定兴县| 灵石县| 罗江县| 白玉县| 蚌埠市| 政和县| 铅山县| 黑山县| 梅州市| 昌江| 闽清县| 黎平县| 新宾| 怀来县| 来安县| 兰考县| 绥江县| 叶城县| 永济市| 祥云县| 科尔| 双桥区| 阆中市| 南阳市| 门头沟区| 和林格尔县| 桐梓县| 南澳县| 鹤岗市| 临桂县|