代理和block區(qū)別及其相應(yīng)優(yōu)缺點(diǎn)

block 和 delegate 都可以通知外面。block 更輕型路捧,使用更簡單关霸,能夠直接訪問上下文,這樣類中不需要存儲臨時(shí)數(shù)據(jù)杰扫,使用 block 的代碼通常會在同一個地方队寇,這樣讀代碼也連貫。delegate 更重一些章姓,需要實(shí)現(xiàn)接口佳遣,它的方法分離開來,很多時(shí)候需要存儲一些臨時(shí)數(shù)據(jù)凡伊,另外相關(guān)的代碼會被分離到各處零渐,沒有 block 好讀。

應(yīng)該優(yōu)先使用 block系忙。而有兩個情況可以考慮 delegate诵盼。

1. 有多個相關(guān)方法。假如每個方法都設(shè)置一個 block, 這樣會更麻煩。而 delegate 讓多個方法分成一組风宁,只需要設(shè)置一次洁墙,就可以多次回調(diào)。當(dāng)多于 3 個方法時(shí)就應(yīng)該優(yōu)先采用 delegate戒财。比如一個網(wǎng)絡(luò)類热监,假如只有成功和失敗兩種情況,每個方法可以設(shè)計(jì)成單獨(dú) block饮寞。但假如存在多個方法孝扛,比如有成功、失敗幽崩、緩存疗琉、https 驗(yàn)證,網(wǎng)絡(luò)進(jìn)度等等歉铝,這種情況下盈简,delegate 就要比 block 要好。

在 swift 中太示,利用 enum,? 多個方法也可以合并成一個 block 接口柠贤。swift 中的枚舉根據(jù)情況不同,可以關(guān)聯(lián)不同數(shù)據(jù)類型类缤。而在 objc 就不建議這樣做臼勉,objc 這種情況下,額外數(shù)據(jù)需要使用 NSObject 或者 字典進(jìn)行強(qiáng)轉(zhuǎn)餐弱,接口就不夠安全宴霸。

2. 為了避免循環(huán)引用,也可以使用 delegate膏蚓。使用 block 時(shí)稍微不注意就形成循環(huán)引用瓢谢,導(dǎo)致對象釋放不了。這種循環(huán)引用驮瞧,一旦出現(xiàn)就比較難檢查出來氓扛。而 delegate 的方法是分離開的,并不會引用上下文论笔,因此會更安全些采郎。假如寫一個庫供他人使用,不清楚使用者的水平如何狂魔。這時(shí)為防止誤用蒜埋,寧愿麻煩一些,笨一些最楷,使用 delegate 來替代 block整份。

將 block 簡單分類待错,有三種情形。

* 臨時(shí)性的皂林,只用在棧當(dāng)中朗鸠,不會存儲起來蚯撩。比如數(shù)組的 foreach 遍歷础倍,這個遍歷用到的 block 是臨時(shí)的,不會存儲起來胎挎。

* 需要存儲起來沟启,但只會調(diào)用一次,或者有一個完成時(shí)期犹菇。比如一個 UIView 的動畫德迹,動畫完成之后,需要使用 block 通知外面揭芍,一旦調(diào)用 block 之后胳搞,這個 block 就可以刪掉。

* 需要存儲起來称杨,可能會調(diào)用多次肌毅。比如按鈕的點(diǎn)擊事件,假如采用 block 實(shí)現(xiàn)姑原,這種 block 就需要長期存儲悬而,并且會調(diào)用多次。調(diào)用之后锭汛,block 也不可以刪除笨奠,可能還有下一次按鈕的點(diǎn)擊。

對于臨時(shí)性的唤殴,只在棧中使用的 block, 沒有循環(huán)引用問題般婆,block 會自動釋放。

而只調(diào)用一次的 block朵逝,需要看內(nèi)部的實(shí)現(xiàn)腺兴,正確的實(shí)現(xiàn)應(yīng)該是 block 調(diào)用之后,馬上賦值為空廉侧,這樣 block 也會釋放页响,同樣不會循環(huán)引用。

而多次調(diào)用時(shí)段誊,block 需要長期存儲闰蚕,就很容易出現(xiàn)循環(huán)引用問題。

Cocoa 中的 API 設(shè)計(jì)也是這樣的连舍,臨時(shí)性的没陡,只會調(diào)用一次的,采用 block。而多次調(diào)用的盼玄,并不會使用 block贴彼。比如按鈕事件,就使用 target-action埃儿。有些庫將按鈕事件從 target-action 封裝成 block 接口, 反而容易出問題器仗。

block的缺點(diǎn):

1. block很難追蹤,難以維護(hù)

我們在調(diào)試的時(shí)候經(jīng)常會單步追蹤到某一個地方之后童番,發(fā)現(xiàn)尼瑪這里有個block精钮,如果想知道這個block里面都做了些什么事情,這時(shí)候就比較蛋疼了剃斧。 block會延長相關(guān)對象的生命周期 block會給內(nèi)部所有的對象引用計(jì)數(shù)加一轨香,這一方面會帶來潛在的retain cycle,不過我們可以通過Weak Self的手段解決幼东。

2. 它會延長對象的生命周期臂容。

在網(wǎng)絡(luò)回調(diào)中使用block,是block導(dǎo)致對象生命周期被延長的其中一個場合根蟹,當(dāng)ViewController從window中卸下時(shí)脓杉,如果尚有請求帶著block在外面飛,然后block里面引用了ViewController(這種場合非常常見)娜亿,那么ViewController是不能被及時(shí)回收的丽已,即便你已經(jīng)取消了請求,那也還是必須得等到請求著陸之后才能被回收买决。

然而使用delegate就不會有這樣的問題沛婴,delegate是弱引用,哪怕請求仍然在外面飛督赤,嘁灯,ViewController還是能夠及時(shí)被回收的,回收之后指針自動被置為了nil躲舌,無傷大雅望迎。

所以平時(shí)盡量不要濫用block绍绘,尤其是在網(wǎng)絡(luò)層這里因篇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沪停,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子约计,更是在濱河造成了極大的恐慌诀拭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煤蚌,死亡現(xiàn)場離奇詭異耕挨,居然都是意外死亡细卧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門筒占,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贪庙,“玉大人翰苫,你說我怎么就攤上這事止邮。” “怎么了革骨?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵农尖,是天一觀的道長析恋。 經(jīng)常有香客問我良哲,道長,這世上最難降的妖魔是什么助隧? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任筑凫,我火速辦了婚禮,結(jié)果婚禮上并村,老公的妹妹穿的比我還像新娘巍实。我一直安慰自己,他們只是感情好哩牍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布棚潦。 她就那樣靜靜地躺著,像睡著了一般膝昆。 火紅的嫁衣襯著肌膚如雪丸边。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天荚孵,我揣著相機(jī)與錄音妹窖,去河邊找鬼。 笑死收叶,一個胖子當(dāng)著我的面吹牛骄呼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播判没,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蜓萄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澄峰?” 一聲冷哼從身側(cè)響起嫉沽,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摊阀,沒想到半個月后耻蛇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踪蹬,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年臣咖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跃捣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡夺蛇,死狀恐怖疚漆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刁赦,我是刑警寧澤娶聘,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站甚脉,受9級特大地震影響丸升,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牺氨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一狡耻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猴凹,春花似錦夷狰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至书劝,卻和暖如春进倍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庄撮。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工背捌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人洞斯。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓毡庆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烙如。 傳聞我的和親對象是個殘疾皇子么抗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354