[iOS]delegate和protocol

今天上班和同事討論工程怎麼組織的時候涉及到這個話題。
iOS開發上對delegate使用普遍。
記在這裏,若是有新人Google到了,但願能有點幫助。java

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

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

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

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

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

@interface  ClassB <ClassADelegate> { } @end

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

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

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

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

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

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

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

那麼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)的了。

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

相關文章
相關標籤/搜索