iOS中如何選擇delegate装黑、通知、KVO(以及三者的區(qū)別)

轉(zhuǎn)載自:http://blog.csdn.net/dqjyong/article/details/7685933

在開發(fā)IOS應用的時候弓熏,我們會經(jīng)常遇到一個常見的問題:在不過分耦合的前提下恋谭,controllers[B]怎么進行通信。在IOS應用不斷的出現(xiàn)三種模式來實現(xiàn)這種通信:

1委托delegation

2通知中心Notification Center

3鍵值觀察key value observing挽鞠,KVO

因此疚颊,那為什么我們需要這些模式以及什么時候用它以及什么時候不用它狈孔。

下面完全根據(jù)我的開發(fā)經(jīng)驗來討論這三中模式。我將討論為什么我覺得某種模式要好于另外一種模式以及為什么我覺得在一定的環(huán)境下某中模式比較好材义。我給出的這些原因并不是圣經(jīng)均抽,而僅僅是個人觀點。如果你有什么不同的觀點或者還可以進行補充的地方其掂,可以聯(lián)系我油挥,一起討論。

上面的三種模式是什么款熬?

三種模式都是一個對象傳遞事件給另外一個對象深寥,并且不要他們有耦合。三種模式都是對象來通知某個事件發(fā)生了的方法贤牛,或者更準確的說惋鹅,是允許其他的對象收到這種事件的方法。這對于一個對象來說殉簸,是非常普通而且必須做的任務闰集,因為沒有通信,controllers將不能整合到整個應用中般卑。controller的另外一個目的是盡可能的自包含武鲁。

我們希望controllers以自己的方式存在,在controllers屢面上不能與其他的controllers進行耦合椭微。Controllers能夠創(chuàng)建其他的controllers而且他們之間可以自由通信洞坑,但是我們不希望controller又回接到創(chuàng)建自己的controller。如果我們耦合了他們蝇率,那么我們將不能復用他們迟杂,以及完全失去對應用中一個獨立的組件的控制。

這三種模式給controllers(也可以是其他的對象)提供通信的方法本慕。下面將描述如何在IOS應用中使用這些模式同樣需要注意的他們在其他的地方也會用到排拷,并且確實是存在。

. delegation

當我們第一次編寫IOS應用時锅尘,我們注意到不斷的在使用“delegate"监氢,并且貫穿于整個SDK。delegation模式不是IOS特有的模式藤违,而是依賴與你過去擁有的編程背景浪腐。針對它的優(yōu)勢以及為什么經(jīng)常使用到,這種模式可能不是很明顯的顿乒。

delegation的基本特征是议街,一個controller定義了一個協(xié)議(即一系列的方法定義)。該協(xié)議描述了一個delegate對象為了能夠響應一個controller的事件而必須做的事情璧榄。協(xié)議就是delegator說特漩,“如果你想作為我的delegate吧雹,那么你就必須實現(xiàn)這些方法”。實現(xiàn)這些方法就是允許controller在它的delegate能夠調(diào)用這些方法涂身,而它的delegate知道什么時候調(diào)用哪種方法雄卷。delegate可以是任何一種對象類型,因此controller不會與某種對象進行耦合蛤售,但是當該對象嘗試告訴委托事情時丁鹉,該對象能確定delegate將響應。

三者優(yōu)缺點:

delegate 的 優(yōu)勢 :

1.非常嚴格的語法悍抑。所有將聽到的事件必須是在delegate協(xié)議中有清晰的定義鳄炉。

2.如果delegate中的一個方法沒有實現(xiàn)那么就會出現(xiàn)編譯警告/錯誤

3.協(xié)議必須在controller的作用域范圍內(nèi)定義

4.在一個應用中的控制流程是可跟蹤的并且是可識別的;

5.在一個控制器中可以定義定義多個不同的協(xié)議搜骡,每個協(xié)議有不同的delegates

6.沒有第三方對象要求保持/監(jiān)視通信過程拂盯。

7.能夠接收調(diào)用的協(xié)議方法的返回值。這意味著delegate能夠提供反饋信息給controller

8.經(jīng)常被用在存在父子關系的對象之間通信记靡,例如控制器和控制器的view(自己加的理解)

缺點 :

1.需要定義很多代碼:1.協(xié)議定義谈竿;2.controller的delegate屬性;3.在delegate本身中實現(xiàn)delegate方法定義

2.在釋放代理對象時摸吠,需要小心的將delegate改為nil空凸。一旦設定失敗,那么調(diào)用釋放對象的方法將會出現(xiàn)內(nèi)存crash

3.在一個controller中有多個delegate對象寸痢,并且delegate是遵守同一個協(xié)議呀洲,但還是很難告訴多個對象同一個事件,不過有可能啼止。

4.經(jīng)常用在一對一的通信道逗。(不知道是缺點還是優(yōu)點,只能算是特點)(自己加的理解)

notification 的 優(yōu)勢 :

1.不需要編寫多少代碼献烦,實現(xiàn)比較簡單

2.對于一個發(fā)出的通知滓窍,多個對象能夠做出反應,即一對多的方式實現(xiàn)簡單

3.controller能夠傳遞context對象(dictionary)巩那,context對象攜帶了關于發(fā)送通知的自定義的信息

缺點 :

1.在編譯期不會檢查通知是否能夠被觀察者正確的處理吏夯;

2.在釋放注冊的對象時,需要在通知中心取消注冊即横;

3.在調(diào)試的時候應用的工作以及控制過程難跟蹤噪生;

4.需要第三方對象來管理controller與觀察者對象之間的聯(lián)系;

5.controller和觀察者需要提前知道通知名稱东囚、UserInfo dictionary keys杠园。如果這些沒有在工作區(qū)間定義,那么會出現(xiàn)不同步的情況;

6.通知發(fā)出后抛蚁,controller不能從觀察者獲得任何的反饋信息(相比較delegate)。

KVO 的 優(yōu)勢 :

1.能夠提供一種簡單的方法實現(xiàn)兩個對象間的同步惕橙。例如:model和view之間同步瞧甩;

2.能夠?qū)Ψ俏覀儎?chuàng)建的對象,即內(nèi)部對象的狀態(tài)改變作出響應弥鹦,而且不需要改變內(nèi)部對象(SKD對象)的實現(xiàn)肚逸;

3.能夠提供觀察的屬性的最新值以及先前值;

4.用key paths來觀察屬性彬坏,因此也可以觀察嵌套對象朦促;

5.完成了對觀察對象的抽象,因為不需要額外的代碼來允許觀察值能夠被觀察

6.可以一對多栓始。

缺點 :

1.我們觀察的屬性必須使用strings來定義务冕。因此在編譯器不會出現(xiàn)警告以及檢查;

2.對屬性重構將導致我們的觀察代碼不再可用幻赚;

3.復雜的“IF”語句要求對象正在觀察多個值禀忆。這是因為所有的觀察代碼通過一個方法來指向;

4.當釋放觀察者時不需要移除觀察者落恼。

1.? 效率 肯定是delegate比NSNotification高箩退。

delegate方法比notification更加直接,最典型的特征是佳谦,delegate方法往往需要關注返回值戴涝, 也就是delegate方法的結果。比如-windowShouldClose:钻蔑,需要關心返回的是yes還是no啥刻。所以delegate方法往往包含 should這個很傳神的詞。也就是好比你做我的delegate矢棚,我會問你我想關閉窗口你愿意嗎郑什?你需要給我一個答案,我根據(jù)你的答案來決定如何做下一 步蒲肋。相反的蘑拯,notification最大的特色就是不關心接受者的態(tài)度, 我只管把通告放出來兜粘,你接受不接受就是你的事情申窘,同時我也不關心結果。所以notification往往用did這個詞匯孔轴,比如 NSWindowDidResizeNotification剃法,那么NSWindow對象放出這個notification后就什么都不管了也不會等待接 受者的反應。

2路鹰、KVO和NSNotification的區(qū)別 :

和delegate一樣贷洲,KVO和NSNotification的作用也是類與類之間的通信收厨,與delegate不同的是1)這兩個都是負責發(fā)出通知,剩下的事情就不管了优构,所以沒有返回值诵叁;2)delegate只是一對一,而這兩個可以一對多钦椭。這兩者也有各自的特點拧额。

總結:

從上面的分析中可以看出3中設計模式都有各自的優(yōu)點和缺點。其實任何一種事物都是這樣彪腔,問題是如何在正確的時間正確的環(huán)境下選擇正確的事物侥锦。下面就講講如何發(fā)揮他們各自的優(yōu)勢,在哪種情況下使用哪種模式德挣。注意使用任何一種模式都沒有對和錯恭垦,只有更適合或者不適合。每一種模式都給對象提供一種方法來通知一個事件給其他對

象盲厌,而且前者不需要知道偵聽者署照。在這三種模式中,我認為KVO有最清晰的使用案例吗浩,而且針對某個需求有清晰的實用性建芙。而另外兩種模式有比較相似的用處,并且經(jīng)常用來給controller間進行通信懂扼。那么我們在什么情況使用其中之一呢禁荸?

根據(jù)我開發(fā)iOS應用的經(jīng)歷,我發(fā)現(xiàn)有些過分的使用通知模式阀湿。我個人不是很喜歡使用通知中心赶熟。我發(fā)現(xiàn)用通知中心很難把握應用的執(zhí)行流程。Userlnfo dictionaries的keys到處傳遞導致失去了同步陷嘴,而且在公共空間需要定義太多的常量映砖。對于一個工作于現(xiàn)有的項目的開發(fā)者來說,如果過分的使用通知中心灾挨,那么很難理解應用的流程邑退。

我覺得使用命名規(guī)則好的協(xié)議和協(xié)議方法定義對于清晰的理解controllers間的通信是很容易的。努力的定義這些協(xié)議方法將增強代碼的可讀性劳澄,以及更好的跟蹤你的app地技。代理協(xié)議發(fā)生改變以及實現(xiàn)都可通過編譯器檢查出來,如果沒有將會在開發(fā)的過程中至少會出現(xiàn)crash秒拔,而不僅僅是讓一些事情異常工作莫矗。甚至在同一事件通知多控制器的場景中,只要你的應用在controller層次有著良好的結構,消息將在該層次上傳遞作谚。該層次能夠向后傳遞直至讓所有需要知道事件的controllers都知道三娩。當然會有delegation模式不適合的例外情況出現(xiàn),而且notification可能更加有效食磕。例如:應用中所有的controller需要知道一個事件尽棕。然而這些類型的場景很少出現(xiàn)。另外一個例子是當你建立了一個架構而且需要通知該事件給正在運行中應用彬伦。

根據(jù)經(jīng)驗,如果是屬性層的時間伊诵,不管是在不需要編程的對象還是在緊緊綁定一個view對象的model對象单绑,我只使用觀察。對于其他的事件曹宴,我都會使用delegate模式搂橙。如果因為某種原因我不能使用delegate,首先我將估計我的app架構是否出現(xiàn)了嚴重的錯誤笛坦。如果沒有錯誤区转,然后才使用notification。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末版扩,一起剝皮案震驚了整個濱河市废离,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌礁芦,老刑警劉巖蜻韭,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柿扣,居然都是意外死亡肖方,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門未状,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俯画,“玉大人,你說我怎么就攤上這事司草〖璐梗” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵翻伺,是天一觀的道長材泄。 經(jīng)常有香客問我,道長吨岭,這世上最難降的妖魔是什么拉宗? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上旦事,老公的妹妹穿的比我還像新娘魁巩。我一直安慰自己,他們只是感情好姐浮,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布谷遂。 她就那樣靜靜地躺著,像睡著了一般卖鲤。 火紅的嫁衣襯著肌膚如雪肾扰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天蛋逾,我揣著相機與錄音集晚,去河邊找鬼。 笑死区匣,一個胖子當著我的面吹牛偷拔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亏钩,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼莲绰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姑丑?” 一聲冷哼從身側響起蛤签,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彻坛,沒想到半個月后顷啼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡昌屉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年钙蒙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间驮。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡躬厌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出竞帽,到底是詐尸還是另有隱情扛施,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布屹篓,位于F島的核電站疙渣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏堆巧。R本人自食惡果不足惜妄荔,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一泼菌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啦租,春花似錦哗伯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恳蹲,卻和暖如春虐块,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嘉蕾。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工非凌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荆针。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像颁糟,于是被迫代替她去往敵國和親航背。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

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