delegate和protocol

轉:http://haoxiang.org/2011/08/ios-delegate-and-protocol/java

http://stackoverflow.com/questions/5431413/difference-between-protocol-and-delegatesios

iOS開發上對delegate使用普遍。
記在這裏,若是有新人Google到了,但願能有點幫助。設計模式

protocol和delegate徹底不是一回事,放在一塊兒說,只是由於咱們常常在同一個頭文件裏看到這兩個word。函數

protocol和java裏interface的概念相似,是Objective-C語法的一部分。
定義protocol以下spa

@protocol ClassADelegate
 
- (void)methodA;
- (void)methodB;
 
@end

那麼就是定義了一組函數,這組函數放在一塊兒叫做一個protocol,也就是協議。設計

函數是須要被實現的,因此若是對於class以下code

@interface ClassB <ClassADelegate> {
}
@end

就叫做ClassB conform to protocol ClassADelegate,也就是說ClassB實現了這個協議,
也就是實現了這一組函數。orm

有了上面這個頭文件,咱們就能夠放心做調用開發

ClassB *b = [[ClassB alloc] init];
[b methodA];
[b methodB];

而不用擔憂出現unrecognized selector sent to instance這種錯誤了。源碼

因此protocol就是一組函數定義,是從類聲明中剝離出來的一組定義。

id<ClassADelegate> b = ...;
[b methodA];

這種用法也常見,b是一個id類型,它知道ClassADelegate這組函數的實現。

那麼delegate是什麼?其實和protocol沒有關係。Delegate自己應該稱爲一種設計模式。
是把一個類本身須要作的一部分事情,讓另外一個類(也能夠就是本身自己)來完成。
好比ClassC

@interface ClassC {
    id delegate;
}
@end

那麼ClassC的實現(.m文件)裏就能夠用delegate這個變量了。
固然這裏徹底能夠用其它名字而不是delegate。

咱們也能夠這樣寫

@interface ClassC {
    ClassB *delegate;
}
@end

這樣咱們知道了delegate是一個ClassB,它就能夠提供ClassB裏的方法。
能夠把一部分ClassC裏的工做放在ClassB裏去實現。
這樣的寫法看起來是否是有點奇怪?或者應該寫成這樣?

@interface ClassC {
    ClassB *classB;
}
@end

.....

delegate沒有了...
因此說其實delegate只是一種模式,你們約定俗成,當把本身內部一部分實現暴露給另一個類去作的時候,就叫實際作事的類爲delegate。

爲何會須要把內部實現提出來給另外一個類作呢?
最多見的目的就是爲了在隱藏實現的前提下,提供一個自定義的機會。
好比Apple提供的iOS SDK裏就有衆多的delegate,好比最經常使用的UITableView,
咱們無法知道Apple怎麼重用UITableViewCell,怎麼處理UITableView裏Cell的增長、刪減,由於咱們沒有源碼。
可是咱們能夠經過實現Delegate的方法來控制一個UITableView的一些行爲。
UITableViewDataSource其實和delegate是同樣同樣的,只是因爲意義不一樣換了個名字罷了。

protocol在此扮演了什麼角色呢?
protocol是一種語法,它提供了一個很方便的、實現delegate模式的機會。
好比寫UITableView的時候,Apple這麼幹
UITableView.m

- (void)doSomething {
    [self blahblah];
 
    [self.delegate guruguru];
 
    [self blahblah];
 }

delegate是咱們寫的類,這個類若是能夠被傳給UITableView作爲其delegate,那惟一要求,就是它實現了

- (void)guruguru;

這個方法。

若是咱們把這個方法定義在一個protocol裏

@protocol XXXProtocol
 
- (void)guruguru;
 
@end

就說明了,UITableView須要的delegate是一個conform to XXXProtocol的類。
這就正好是

id<XXXProtocol>

表達的意思。
不管具體的類是什麼,它還有其它什麼方法,只要它conform to這個protocol,
就說明它能夠被傳給UITableView,做爲它的delegate。
那麼Apple爲了讓咱們知道這個protocol是delegate須要conform的protocol,
它就把XXXProtocol改爲了UITableViewDelegate

這樣咱們看到protocol的名字裏有Delegate,就知道這個protocol裏的函數是用來作自定義(Customization)的了。

代碼最終仍是給人看的,公司裏尤爲如此。
你們都但願對方把事情講得清晰易懂,若是在再有兩句俗語或者行話那你們就很開心了 :]

結論:protocol 是一種語法。delegate 是一種設計模式。delegate不過是對一種協議使用方法的命名。相似的狀況還有datasource。其實本質都是利用協議實現。

相關文章
相關標籤/搜索