亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

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

系統 2800 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條評論
主站蜘蛛池模板: 99热这里只有精品18 | 国产成人精品免费 | 欧美精品在线一区二区三区 | 免费一级黄色录像 | 久久久欧美综合久久久久 | 天天视频一区二区三区 | 成人国产精品久久久免费 | 青青青青久在线观看视频 | 精品国产自在现线看久久 | 在线播放真实国产乱子伦 | 男人的天堂一区二区视频在线观看 | 国产最新精品精品视频 | 日韩欧美国产中文字幕 | 一级成人| 国产亚洲欧美在线 | 99久久免费国产精品m9 | 久久福利在线 | 天堂网一区二区 | 五月天婷婷激情视频 | 九九99九九视频在线观看 | 真实国产乱弄免费视频 | 国产aa免费视频 | 欧美日韩中文在线观看 | 一级日本高清视频免费观看 | 精品一区二区视频 | 福利视频999| 欧美成年黄网站色高清视频 | 国产亚洲精品美女一区二区 | 亚洲欧美精品中文字幕 | 米奇影视7777 | 亚洲最大在线 | 国产精品久久久久一区二区 | 亚洲视频在线精品 | 四虎新地址 | 四虎4hu影库永久地址 | 久久天天躁综合夜夜黑人鲁色 | 欧美成人久久一级c片免费 欧美成人剧情中文字幕 | 中国一级特黄真人毛片免 | 久久香蕉国产线看观看精品yw | 亚洲精品亚洲人成毛片不卡 | 亚洲国产大片 |