版權聲明:本文爲博主原創文章,未經博主容許不得轉載。html
協議(protocol)是Objective-c中一個很是重要的語言特性,從概念上講,很是相似於JAVA中接口. 一個協議其實就是一系列有關聯的方法的集合(爲方便後面敘述,咱們把這個協議命名爲myProtocol)。協議中的方法並非由協議自己去實現,相反而 是由遵循這個協議的其餘類來實現。換句話說,協議myProtocol只是完成對協議函數的聲明而並無論這些協議函數的具體實現。app
聲明一個協議的語法很是簡單:框架
協議接口分爲required和optional兩類。required顧名思義是說遵照這個協議的那個類「必需要」實現的接口,而optional則是能夠實現也能夠不實現的。協議接口的定義和普通的函數定義是同樣的。函數
最後一行@end表示協議定義結束。這個協議的定義一般是在.h文件中。測試
定義一個類遵循這個協議:ui
爲何須要協議?spa
蘋果的官方文檔指出三個緣由:.net
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: