delegate和protocol(區(qū)別)

轉(zhuǎn)帖H陈濉玻募!

protocol和delegate完全不是一回事,放在一起說(shuō)滑肉,只是因?yàn)槲覀兘?jīng)常在同一個(gè)頭文件里看到這兩個(gè)word包各。

協(xié)議(protocol),就是使用了這個(gè)協(xié)議后就要按照這個(gè)協(xié)議來(lái)辦事靶庙,協(xié)議要求實(shí)現(xiàn)的方法就一定要實(shí)現(xiàn)问畅。

委托(delegate),顧名思義就是委托別人辦事六荒,就是當(dāng) 一件事情發(fā)生后护姆,自己不處理,讓別人來(lái)處理掏击。

舉個(gè)淺顯的例子:

我上班的工作主要內(nèi)容包括 (1)寫(xiě)代碼(2)寫(xiě)文檔(3)測(cè)試程序(4)接電話(huà)(5)會(huì)見(jiàn)客戶(hù)

(1)(2)我自己全權(quán)負(fù)責(zé)卵皂,但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找個(gè)助手(delegate)幫我做這些事砚亭,于是我定了一個(gè)招聘要求(Protocol)灯变,里寫(xiě)明我的助手需要會(huì)做(3)(4)(5)這三件事。很快捅膘,我招到一個(gè)助手添祸。

即:我.delegate = 助手;

于是以后每當(dāng)我遇到需要測(cè)試程序或者接電話(huà)的活,我就把他轉(zhuǎn)交給助手(delegate)去處理篓跛,助手處理完后如果有處理結(jié)果(返回值)助手會(huì)告訴我膝捞,也許我會(huì)拿來(lái)用。如果不需要或者沒(méi)有結(jié)果愧沟,我就接著做下面的事蔬咬。。

protocol和java里interface的概念類(lèi)似沐寺,是Objective-C語(yǔ)法的一部分林艘。

定義protocol如下

C代碼

@protocol?ClassADelegate

-?(void)methodA;

-?(void)methodB;

@end

那么就是定義了一組函數(shù),這組函數(shù)放在一起叫作一個(gè)protocol混坞,也就是協(xié)議狐援。

函數(shù)是需要被實(shí)現(xiàn)的钢坦,所以如果對(duì)于class如下

C代碼

@interface?ClassB??{

}

@end

就叫作ClassB conform to protocol ClassADelegate,也就是說(shuō)ClassB實(shí)現(xiàn)了這個(gè)協(xié)議啥酱,

也就是實(shí)現(xiàn)了這一組函數(shù)爹凹。

有了上面這個(gè)頭文件,我們就可以放心作調(diào)用

C代碼

ClassB?*b?=?[[ClassB?alloc]?init];

[b?methodA];

[b?methodB];

而不用擔(dān)心出現(xiàn)unrecognized selector sent to instance這種錯(cuò)誤了镶殷。

所以protocol就是一組函數(shù)定義禾酱,是從類(lèi)聲明中剝離出來(lái)的一組定義。

C代碼

id?b?=?...;

[b?methodA];

這種用法也常見(jiàn)绘趋,b是一個(gè)id類(lèi)型颤陶,它知道ClassADelegate這組函數(shù)的實(shí)現(xiàn)。

那么delegate是什么陷遮?其實(shí)和protocol沒(méi)有關(guān)系滓走。Delegate本身應(yīng)該稱(chēng)為一種設(shè)計(jì)模式。

是把一個(gè)類(lèi)自己需要做的一部分事情帽馋,讓另一個(gè)類(lèi)(也可以就是自己本身)來(lái)完成搅方。

比如ClassC

C代碼

@interface?ClassC?{

id?delegate;

}

@end

那么ClassC的實(shí)現(xiàn)(.m文件)里就可以用delegate這個(gè)變量了。

當(dāng)然這里完全可以用其它名字而不是delegate茬斧。

我們也可以這樣寫(xiě)

C代碼

@interface?ClassC?{

ClassB?*delegate;

}

@end

這樣我們知道了delegate是一個(gè)ClassB腰懂,它就可以提供ClassB里的方法。

可以把一部分ClassC里的工作放在ClassB里去實(shí)現(xiàn)项秉。

這樣的寫(xiě)法看起來(lái)是不是有點(diǎn)奇怪绣溜?或者應(yīng)該寫(xiě)成這樣?

C代碼

@interface?ClassC?{

ClassB?*classB;

}

@end

delegate沒(méi)有了…

所以說(shuō)其實(shí)delegate只是一種模式娄蔼,大家約定俗成怖喻,當(dāng)把自己內(nèi)部一部分實(shí)現(xiàn)暴露給另外一個(gè)類(lèi)去做的時(shí)候,就叫實(shí)際做事的類(lèi)為delegate岁诉。

為什么會(huì)需要把內(nèi)部實(shí)現(xiàn)提出來(lái)給另一個(gè)類(lèi)做呢锚沸?

最常見(jiàn)的目的就是為了在隱藏實(shí)現(xiàn)的前提下,提供一個(gè)自定義的機(jī)會(huì)涕癣。

比如Apple提供的iOS SDK里就有眾多的delegate哗蜈,比如最常用的UITableView,

我們沒(méi)法知道Apple怎么重用UITableViewCell坠韩,怎么處理UITableView里Cell的增加距潘、刪減,因?yàn)槲覀儧](méi)有源碼只搁。

但是我們可以通過(guò)實(shí)現(xiàn)Delegate的方法來(lái)控制一個(gè)UITableView的一些行為音比。

UITableViewDataSource其實(shí)和delegate是一樣一樣的,只是由于意義不同換了個(gè)名字罷了氢惋。

protocol在此扮演了什么角色呢洞翩?

protocol是一種語(yǔ)法稽犁,它提供了一個(gè)很方便的、實(shí)現(xiàn)delegate模式的機(jī)會(huì)骚亿。

比如寫(xiě)UITableView的時(shí)候已亥,Apple這么干

UITableView.m

C代碼

-?(void)doSomething?{

[self?blahblah];

[self.delegate?guruguru];

[self?blahblah];

}

delegate是我們寫(xiě)的類(lèi),這個(gè)類(lèi)如果可以被傳給UITableView做為其delegate来屠,那唯一要求陷猫,就是它實(shí)現(xiàn)了

- (void)guruguru;

這個(gè)方法。

如果我們把這個(gè)方法定義在一個(gè)protocol里

C代碼

@protocol?XXXProtocol

-?(void)guruguru;

@end

就說(shuō)明了的妖,UITableView需要的delegate是一個(gè)conform to XXXProtocol的類(lèi)。

這就正好是

id

表達(dá)的意思足陨。

無(wú)論具體的類(lèi)是什么嫂粟,它還有其它什么方法,只要它c(diǎn)onform to這個(gè)protocol墨缘,

就說(shuō)明它可以被傳給UITableView星虹,作為它的delegate。

那么Apple為了讓我們知道這個(gè)protocol是delegate需要conform的protocol镊讼,

它就把XXXProtocol改成了UITableViewDelegate

這樣我們看到protocol的名字里有Delegate宽涌,就知道這個(gè)protocol里的函數(shù)是用來(lái)做自定義(Customization)的了。

來(lái)源:http://haoxiang.org/2011/08/ios-delegate-and-protocol/

Protocol 的其它問(wèn)題

1. 使用時(shí)為什么要加上 iOS.delegate = self

物件名稱(chēng).delegate = self蝶棋,是在采用任何協(xié)定時(shí)

一定會(huì)看到的一行程式碼卸亮,由于定義協(xié)定的類(lèi)別并不需要實(shí)作協(xié)定內(nèi)的方法,因?yàn)閷?shí)作的部份是由采納協(xié)定的類(lèi)別來(lái)實(shí)作玩裙,但是它又必須要知道是由哪一個(gè)類(lèi)別來(lái)實(shí)

作兼贸,因此我們必須要把采納協(xié)定類(lèi)別的 instance 交給定義協(xié)定的類(lèi)別,讓它來(lái)使用吃溅。

另一方面并不是任何類(lèi)別都可以將 instance 傳給定義協(xié)定的類(lèi)別來(lái)使用溶诞,其原因是,我們?cè)诙x此協(xié)定的類(lèi)別里有宣告 delegate

變數(shù)時(shí)决侈,有限定它必須要采納此協(xié)定(id delegate)如果沒(méi)有采用該協(xié)定就將 instance 傳給定義該協(xié)定的類(lèi)別螺垢,Xcode

同樣會(huì)發(fā)出警告訊息。

2. 為什么協(xié)定的生效位置不能寫(xiě)在建構(gòu)式中

協(xié)定的生效位置寫(xiě)在建構(gòu)式中赖歌,并不會(huì)造成程式編譯上的任何問(wèn)題枉圃,因?yàn)檫@是屬于邏輯上的錯(cuò)誤,協(xié)定要正常生效它必須要知道實(shí)作它方法的類(lèi)別的

instance俏站,如果將生效的位置寫(xiě)在建構(gòu)式中讯蒲,在建立定義此協(xié)定的形態(tài)的變物件時(shí),它的確會(huì)去觸發(fā)此協(xié)定內(nèi)的方法肄扎,但是由于并沒(méi)有給它實(shí)作此協(xié)定方法

類(lèi)別的 instance墨林,因此不會(huì)有任何效果產(chǎn)生赁酝,反之,如果一定要將生效的位置寫(xiě)在建構(gòu)式中旭等,那么在初始化時(shí)就必須要設(shè)定好 delegate

才行酌呆,也就是使用初始化的方法函式里還必須要帶入一個(gè)參數(shù)物件好指定給 delegate。

3. 在定義協(xié)定時(shí)同時(shí)也可以采用其他的協(xié)定

如果在定義協(xié)定時(shí)同時(shí)又採(cǎi)用其他的協(xié)定搔耕,這會(huì)導(dǎo)致之后採(cǎi)納此協(xié)定的類(lèi)別,它必須同時(shí)實(shí)作出兩個(gè)協(xié)定內(nèi)的方法弃榨,同樣地菩收,你也可以利用此方式來(lái)擴(kuò)充那些已經(jīng)存在的協(xié)定。

C代碼

@protocol?FurnaceDelegate?<其它可能的協(xié)定名稱(chēng)>

4. 使用 @optional 提供選擇性的實(shí)作

@optional鲸睛,如同它字面上的意義娜饵,在 @optional 之后的方法都可以是選擇性的實(shí)作,在定義協(xié)定時(shí)使用此方法官辈,可以讓之后採(cǎi)納此協(xié)定的類(lèi)別不一定要完全實(shí)作出協(xié)定內(nèi)的所有方法箱舞。

C代碼

@protocol?FurnaceDelegate

-?(void)whenCalledDelegeteFunction;

@optional

-(void)optionalDelegeteFunction;

@end

來(lái)源:http://furnacedigital.blogspot.com/2012/01/protocol.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拳亿,隨后出現(xiàn)的幾起案子晴股,更是在濱河造成了極大的恐慌,老刑警劉巖肺魁,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件电湘,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡万搔,警方通過(guò)查閱死者的電腦和手機(jī)胡桨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瞬雹,“玉大人昧谊,你說(shuō)我怎么就攤上這事⌒锇疲” “怎么了呢诬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)胖缤。 經(jīng)常有香客問(wèn)我尚镰,道長(zhǎng),這世上最難降的妖魔是什么哪廓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任狗唉,我火速辦了婚禮,結(jié)果婚禮上涡真,老公的妹妹穿的比我還像新娘分俯。我一直安慰自己肾筐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布缸剪。 她就那樣靜靜地躺著吗铐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杏节。 梳的紋絲不亂的頭發(fā)上唬渗,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音奋渔,去河邊找鬼镊逝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嫉鲸,可吹牛的內(nèi)容都是我干的蹋半。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼充坑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了染突?” 一聲冷哼從身側(cè)響起捻爷,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎份企,沒(méi)想到半個(gè)月后也榄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡司志,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年甜紫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骂远。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡囚霸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出激才,到底是詐尸還是另有隱情拓型,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布瘸恼,位于F島的核電站劣挫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏东帅。R本人自食惡果不足惜压固,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望靠闭。 院中可真熱鬧帐我,春花似錦坎炼、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至矿咕,卻和暖如春抢肛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碳柱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工捡絮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓迟蜜,卻偏偏與公主長(zhǎng)得像愧杯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子的圆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容