今天上班和同事討論工程怎麼組織的時候涉及到這個話題。
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)的了。
代碼最終仍是給人看的,公司裏尤爲如此。 你們都但願對方把事情講得清晰易懂,若是在再有兩句俗語或者行話那你們就很開心了 :]