Objective-C 協議(protocol)

來源:互聯網
上載者:User

標籤:

協議(protocol)是Objective-c中一個非常重要的語言特性,從概念上講,非常類似於JAVA中介面. 一個協議其實就是一系列有關聯的方法的集合(為方便後面敘述,我們把這個協議命名為myProtocol)。協議中的方法並不是由協議本身去實現,相反而是由遵循這個協議的其他類來實現。換句話說,協議myProtocol只是完成對協議函數的聲明而並不管這些協議函數的具體實現。

聲明一個協議的文法非常簡單:

 

[cpp] view plaincopy 
  1. @protocol myProtocol <NSObject>  
  2. @required  
  3. -(void) protocolNameA:(NSString*)string;  
  4. @optional  
  5. -(void) protocolNameB:(NSString*)string;  
  6. @end  

 

 

第一行是聲明這個協議的名字為myProtocol。角括弧中的NSObject本身也是一個協議,其中定義了很多基本的協議函數,比如performSelector,isKindOfClass,respondsToSelector,conformsToProtocol,retain,release等。

協議介面分為required和optional兩類。required顧名思義是說遵守這個協議的那個類“必須要”實現的介面,而optional則是可以實現也可以不實現的。協議介面的定義和普通的函數定義是一樣的。

最後一行@end表示協議定義結束。這個協議的定義通常是在.h檔案中。

 

定義一個類遵循這個協議:

 

[cpp] view plaincopy 
  1. @interface myClass  <myProtocol>  
  2. @interface myClass :NSObject<myProtocol>  
  3. @interface myClass :NSObject<myProtocol, NSCoding>  

上面分別是三種不同的情況。編譯的時候編譯器會自動檢查myClass是否實現了myProtocol中的必要的(@required)介面。如果沒有實現則會發出一個警告資訊。另外需要注意的是,如果有繼承自myClass的子類,這些子類也是會自動遵循myClass所遵循的協議的,而且也可以重載這些介面。

 

 

為什麼需要協議?

蘋果的官方文檔指出三個原因:

 

    • To declare methods that others are expected to implement

    • To declare the interface to an object while concealing its class

    • To capture similarities among classes that are not hierarchically related

       

      其實還有第四個很重要的原因,那就是減少繼承類的複雜性。一個經典的例子就是iOS UI架構裡面的UITableViewController類。假如沒有“協議”功能,使用者就必須選擇用繼承和重載介面的方法來實現複雜的UI控制以及其他事件的處理——這就對基類的設計提出了更大的挑戰了。對於像這樣一個table view,一個很好的實現方法就是採用協議,由協議裡的介面來控制不同的資料來源以及各種複雜的使用者操作。UIKit中設計了兩個很好的協議UITableViewDelegate,UITableViewDataSource來實現UITableViewController的控制。任何遵循這兩個協議的類都可以實現對UITableView的控制。

       

      關於 id類型的運用:(不喜歡鑽牛角尖的朋友,可以略過這一部分)

      id 類型在iOS中是一個通用類型,有點類似C語言的void*類型。編譯器不能檢查到定義為id類型的變數的實際類型,id類型的識別是發生在運行時階段。但是我們可以用 id<protocol_name> obj;這樣的文法形式在編譯階段就可以讓編譯器知道obj只可以發送protocol_name中的訊息,如果所發送的訊息不在protocol_name中,編譯器會給一個警告資訊“Instance method ‘xxxx:‘ not found......”。這種情況多用於代理模式的實現,比如某一個類有一個delegate 的property:

       

      [cpp] view plaincopy 
      1. id <myProtocol> delegate;  

      這樣,在編譯階段我們就可以知道用delegate所發送的訊息是不是在它所遵循的myProtocol中的訊息。好了, 到這裡筆者鑽起了牛角尖,我把id後面的 <myProtocol>刪掉,然後用delegate發送一個並不存在於myProtocol中的訊息,結果編譯器還是給了“Instance method ‘xxxx:‘ not found......”的警告資訊。更奇怪的是,當發送一個存在於myProtocol中的訊息時,編譯器竟然沒有這樣的警告資訊。這兩個測試並不能說明之前的解釋是錯誤的,姑且認為id<myProtocol> delegate這種寫法是為了便於知道這個delegate遵循了myProtocol的協議吧。

Objective-C 協議(protocol)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.