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

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

系統 3166 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條評論
主站蜘蛛池模板: 亚洲国产天堂久久九九九 | 亚洲精品中文字幕乱码一区二区 | 中文字幕一区二区三区亚洲精品 | 久久精品免费看 | 国产在线精品一区免费香蕉 | 国产国拍亚洲精品午夜不卡17 | aaa级精品久久久国产片 | 国产这里有精品 | 乱子伦有声小说mp3 仑乱高清在线一级播放 | 色妞欧美| 成人毛片在线播放 | 亚洲第成色999久久网站 | 天天插天天射天天干 | 国产极品嫩模大尺度福利视频 | 一级一级毛片免费播放 | 精品国产一级毛片大全 | 性色生活免费看性大片 | 国产麻豆之光e奶女教师 | 亚洲综合精品一二三区在线 | 亚洲一区二区三区四区 | 四虎永久免费地址ww417 | 亚洲精品你懂的 | 性生大片一级毛片免费观看 | 亚洲一区二区三区视频 | 亚洲国产成人综合 | 欧美日本一本 | 欧美专区在线观看 | 老师邪恶影院a啦啦啦影院 老师在办公室被躁到白浆 老湿机午夜影院 | 中文字幕五月天 | 97视频免费上传播放 | 热久久视久久精品18国产 | 国产高清在线精品一区二区三区 | 爱做久久久久久久久久 | 日韩欧美综合在线二区三区 | 久久4| 午夜视频久久 | 中文字幕在线免费看 | 成人国产精品免费网站 | 成人牲交一极毛片 | 大尺度视频网站久久久久久久久 | 国产一区二区三区不卡在线观看 |