2011-03-25 59 views

回答

74

使用Objective-C中的(@protocol語法)聲明的協議用於聲明類「採用」(聲明它將使用此協議)將實現的一組方法。這意味着你可以在你的代碼中指定「只要它實現了一個特定的協議,你不關心使用哪個類」。這可以在Objective-C進行如下:

id<MyProtocol> instanceOfClassThatImplementsMyProtocol;

如果你在你的代碼說明這一點,那麼任何類,「符合」的協議MyProtocol可以在可變instanceOfClassThatImplementsMyProtocol使用。這意味着使用這個變量的代碼知道它可以使用這個方法在MyProtocol中定義的這個特定的變量,而不管它是什麼類。這是避免繼承設計模式的好方法,並且避免了緊耦合。

代表是使用協議的語言功能。 delegation design pattern是一種設計您的代碼以在必要時使用協議的方式。在Cocoa框架中,委託設計模式用於指定符合特定協議的類的實例。這個特定的協議指定了委託類應該實現的方法,以便在給定的事件中執行特定的操作。使用委託的類知道它的委託協議,所以它知道它可以在給定的時間調用實現的方法。這種設計模式是解耦類的一種很好的方式,因爲它使得交換一個委託實例變得非常容易 - 程序員必須做的是確保替換實例或類符合必要的協議(即它實現了協議中指定的方法)!

協議和委託並不僅限於Objective-C和Mac/iOS開發,但Objective-C語言和Apple框架大量使用了這種令人敬畏的語言功能和設計模式。

編輯:

下面是一個例子。在Cocoa Touch的UIKit框架中,有一個UITextFieldDelegate協議。這個協議定義了一系列的方法,這些方法是實例應該實現的一個UITextField的代表。換句話說,如果您想要將代理指定給UITextField(使用delegate屬性),最好確保此類符合UITextFieldDelegate。事實上,由於的UITextField委託屬性定義爲:

@property(nonatomic, weak) id<UITextFieldDelegate> delegate

編譯器會,如果你指定一個類,它沒有實現該協議給予警告。這非常有用。你必須聲明一個類實現了一個協議,並且在說明它的時候,你讓其他類知道他們可以以特定的方式與你的類進行交互。所以,如果你指定的實例MyTextFieldDelegateClassdelegate財產的UITextField,在的UITextField知道,它可以調用一些特定的方法(與文本輸入,選擇等)你MyTextFieldDelegateClass的。它知道這是因爲MyTextFieldDelegateClass已經表示它將實現UITextFieldDelegate協議。

最終,這一切都會在您的項目代碼中產生更大的靈活性和適應性,我相信您在使用此技術後很快就會意識到這一點! :)

+3

所以協議爲你做什麼,委託方式去做吧? – 3lvis 2012-09-06 06:14:30

+13

我不確定我是否跟着你。委託是一種設計模式,它允許一個類以一種解耦代碼的方式承擔另一個責任(非常好,靈活的事情)。協議是一種Objective-C語言功能,允許您編寫和使用使用委託概念的代碼。 – 2012-09-06 10:40:41

+0

@JamesBedford你能告訴我「id 是什麼意思」 – Exploring 2013-08-13 06:59:12

13

團:代理上另一個對象的代(設計在糟糕圖案)

它是一個設計圖案在其中一個對象被稱爲委託的行動代表的,並在該請求,另一個對象。在執行過程中,它向它的代理髮送一條消息;該消息告訴委託人某些事件即將發生並請求一些響應。代理實現由消息調用的方法並返回適當的值

一個示例是appdelegate對象代表appobject行事。

協議:啓用對象通過繼承

的協議不相關之間的通信是一個編程接口,其方法中的任何類可以implement.Protocols是目標C語言特徵 .Simply發言的列表的聲明任何類都可以實現的方法。要使用它,您需要確認協議。 示例是UITableviewDatasource協議,其方法cellforRowAtIndexPath在協議中聲明,但我們實現它以創建tableview。

參見https://developer.apple.com/library/mac/referencelibrary/GettingStarted/RoadMapOSX/books/StreamlineYourAppswithDesignPatterns/StreamlineYourApps/StreamlineYourApps.html

12

協議是一組方法(無論是可選的或必需)的那些將被符合該協議的類來實現。而委託則是指那個符合該協議的類,並且將遵守協議中定義的實現方法。

查看this瞭解更多詳情。

+1

我見過的最好的解釋,謝謝。 – 2017-08-28 18:40:03

+0

請注意在這種情況下的答案.. – NSPratik 2017-08-28 18:50:50

+1

別擔心,我做到了。 – 2017-08-28 20:14:24

4

讓看到委託的聲明在程序

id<myProtocol> *delegatingObject; 

的delegatingObject保持對其他對象並在適當的時間的參考將消息發送到該對象。

協議是一組可以由任何類實現的相關屬性和方法。它暗示確認myProtocol(相關屬性和方法組)的任何對象(id類型)都可以作爲委託來工作,或者你可以說任何具有所需學位(協議)的人(id)都可以作爲一個工作組來使用教師(代表)。

4

一種 mportant p rerequisite是理解協議˚F IRST 然後代表。我建議你先看看this簡短教程,然後看What is a Protocol?。此外,您必須知道類別和協議之間的區別,請參閱Objective-C: Class versus ProtocolWhat is the point of Protocols?


protocol:只是一個函數來實現的藍圖。任何採用該藍圖的課程都必須實施這些功能。 (請不要誤會實現一個函數調用一個功能)

delegate:是你也什麼delegat- 荷蘭國際集團類是做繼承例如

例如,您有一個viewController並想要下載圖像或想要獲得客戶與商店的距離,所以您不需要自己完成所有工作,而只需要一箇中型對象,即可爲您完成此操作。該對象被稱爲委託對象。通常你會做一些這樣:

class ViewController : UIViewController , DownloaderDelegate{ 
//other code 

(inside viewDidLoad or elsewhere) you write: 
downloaderHandler.delegate = self // now self can also do WHATEVER the delegate can do...previously it was only a viewController but now it's 'almost' also a downloader 

非常相似,你符合一個tableViewDelegate

class ViewController : UIViewController , UITableViewDelegate{ 
//other code 
(inside viewDidLoad or elsewhere) you write 
tableView.delegate = self 

self現在還可以做的tableView相關的東西做什麼。


delegate: 但是該對象(委託)是一個普通的對象(ID或任何)。這是愚蠢的!你必須說:「嘿,你需要具備特定的功能,以符合我們爲你定義的協議(我們不會擴展任何或id,因爲它會變得愚蠢,(取而代之)我們製作一個非常明確的限制協議「在Objective-C
這是一個純粹的香草id,所以你做

@property (weak) id<DownloaderProtocol>delegate; 

斯威夫特*這是稍微容易一些,你這樣做:

weak var delegate:DownloaderProtocol? 

協議來救援......的德legate實現(不使用)功能,但它適合您的委派類的需要。


*:在斯威夫特你沒有id還是你不需要它的等效Any因爲斯威夫特協議也是一等公民類型