在說之前珊皿,先說明protocol和delegate完全不是一回事,放在一起說巨税,只是因?yàn)槲覀兘?jīng)常在同一個頭文件里看到這兩個word蟋定。
委托(代理模式)(Delegate):顧名思義就是委托別人辦事,就是當(dāng) 一件事情發(fā)生后草添,自己不處理驶兜,讓別人來處理。
協(xié)議 (Protocol):就是使用了這個協(xié)議后就要按照這個協(xié)議來辦事远寸,協(xié)議要求實(shí)現(xiàn)的方法就一定要實(shí)現(xiàn)批什。
就是我有一個任務(wù)完成一個app 我只會寫iOS端的前臺璧尸,我需要找人寫后臺腻窒,即委托(Delegate)人寫后臺懊烤,我倆合作時要有個協(xié)議(Protocol),完成之后各分多少錢倡怎。迅耘。。
?協(xié)議(Protocol)
protocol和java里interface的概念類似监署,是Objective-C語法的一部分颤专。(其實(shí)我跟不不知道什么java的interface,喵)
定義protocol如下
@protocol ClassADelegate
-(void)methodA;
-(void)methodB;
@end
那么就是定義了一組函數(shù)钠乏,這組函數(shù)放在一起叫作一個protocol栖秕,也就是協(xié)議。
函數(shù)是需要被實(shí)現(xiàn)的晓避,所以如果對于class如下
@interface ClassB<ClassADelegate>{
}
@end
就叫作ClassB conform to protocol ClassADelegate簇捍,也就是說ClassB實(shí)現(xiàn)了這個協(xié)議,
也就是實(shí)現(xiàn)了這一組函數(shù)俏拱。
有了上面這個頭文件暑塑,我們就可以放心作調(diào)用
ClassB*b=[[ClassB alloc]init];
[b methodA];
[b methodB];
而不用擔(dān)心出現(xiàn)unrecognized selector sent to instance這種錯誤了。
所以protocol就是一組函數(shù)定義锅必,是從類聲明中剝離出來的一組定義事格。
id<ClassADelegate>b=...;
[b methodA];
這種用法也常見,b是一個id類型搞隐,它知道ClassADelegate這組函數(shù)的實(shí)現(xiàn)驹愚。
委托(Delegate)
Delegate本身應(yīng)該稱為一種設(shè)計模式。
是把一個類自己需要做的一部分事情劣纲,讓另一個類(也可以就是自己本身)來完成逢捺。
就是調(diào)用自己定義方法,別的類來實(shí)現(xiàn)癞季。比如ClassC
@interface ClassC{
id delegate;
}@end
那么ClassC的實(shí)現(xiàn)(.m文件)里就可以用delegate這個變量了劫瞳。
當(dāng)然這里完全可以用其它名字而不是delegate。
我們也可以這樣寫
@interface ClassC{
ClassB *delegate;
}@end
這樣我們知道了delegate是一個ClassB绷柒,它就可以提供ClassB里的方法柠新。
可以把一部分ClassC里的工作放在ClassB里去實(shí)現(xiàn)。
這樣的寫法看起來是不是有點(diǎn)奇怪辉巡?或者應(yīng)該寫成這樣恨憎?
@interface ClassC{
ClassB *classB;
}@end
delegate沒有了...
所以說其實(shí)delegate只是一種模式,大家約定俗成郊楣,當(dāng)把自己內(nèi)部一部分實(shí)現(xiàn)暴露給另外一個類去做的時候憔恳,就叫實(shí)際做事的類為delegate。
為什么會需要把內(nèi)部實(shí)現(xiàn)提出來給另一個類做呢净蚤?
最常見的目的就是為了在隱藏實(shí)現(xiàn)的前提下钥组,提供一個自定義的機(jī)會。
比如Apple提供的iOS SDK里就有眾多的delegate今瀑,比如最常用的UITableView程梦,
我們沒法知道Apple怎么重用UITableViewCell点把,怎么處理UITableView里Cell的增加、刪減屿附,因?yàn)槲覀儧]有源碼郎逃。
但是我們可以通過實(shí)現(xiàn)Delegate的方法來控制一個UITableView的一些行為。
UITableViewDataSource其實(shí)和delegate是一樣一樣的挺份,只是由于意義不同換了個名字罷了褒翰。
比如寫UITableView的時候,Apple這么干
UITableView.m
-(void)doSomething{
[self blahblah];
[self.delegate guruguru];
[self blahblah];
}
delegate是我們寫的類匀泊,這個類如果可以被傳給UITableView做為其delegate优训,那唯一要求,就是它實(shí)現(xiàn)了
-(void)guruguru;
這個方法各聘。
如果我們把這個方法定義在一個protocol里
@protocol XXXProtocol
-(void)guruguru;
@end
就說明了揣非,UITableView需要的delegate是一個conform to XXXProtocol的類。
這就正好是
id<XXXProtocol>
表達(dá)的意思躲因。
無論具體的類是什么妆兑,它還有其它什么方法,只要它c(diǎn)onform to這個protocol毛仪,
就說明它可以被傳給UITableView搁嗓,作為它的delegate。
那么Apple為了讓我們知道這個protocol是delegate需要conform的protocol箱靴,
它就把XXXProtocol改成了UITableViewDelegate
這樣我們看到protocol的名字里有Delegate腺逛,就知道這個protocol里的函數(shù)是用來做自定義(Customization)的了。
抄到這里衡怀,委托和協(xié)議大概我都明白了棍矛,不知道大家是否理解了,面試一般都會問的哦