參考:http://www.ithao123.cn/content-8349585.html
1.Delegate(代理、委托)
代理幾乎是iOS開發(fā)中最常用的傳值方式铝耻,在項目中的AppDelegate就是使用的這種設(shè)計模式忽孽,不僅如此,還有很多原生的控件也使用的這種設(shè)計模式,比如:UITextFiled姊途,UITableView等等涉瘾。
Delegate的優(yōu)點(diǎn)和缺陷:
優(yōu)點(diǎn):
1.減少代碼的耦合性,使事件監(jiān)聽和事件處理相分離捷兰。
2.清晰的語法定義立叛,減少維護(hù)成本,較強(qiáng)的代碼可讀性贡茅。
3.不需要創(chuàng)建第三方來監(jiān)聽事件和傳輸數(shù)據(jù)秘蛇。
4.一個控制器可以實(shí)現(xiàn)多個代理,滿足自定義開發(fā)需求顶考,可選必選有較大的靈活性赁还。
缺點(diǎn):
1.實(shí)現(xiàn)委托的代碼過程比較繁瑣。
2.當(dāng)實(shí)現(xiàn)跨層傳值監(jiān)聽的時候?qū)⒓哟蟠a的耦合性驹沿,并且程序的層次結(jié)構(gòu)將變的混亂艘策。
3.當(dāng)對多個對象同時傳值響應(yīng)的時候,委托的易用性將大大降低渊季。
2.NotificationCenter(通知)
通知也是iOS開發(fā)中常用的一種傳值響應(yīng)方法朋蔫,例如在AVFoundation框架中的MPMoviePlayerController在監(jiān)聽播放狀態(tài)改變,播放停止等事件時使用的也正是NotificationCenter却汉。
NSNotification采用的單例設(shè)計模式驯妄,當(dāng)給通知中心注冊一個key以后,那么無論在什么地方只要給通知中心發(fā)送一個這個key的消息病涨,那么就實(shí)現(xiàn)了通信傳值富玷,注冊的通知的對象就會調(diào)用相應(yīng)的方法。
優(yōu)點(diǎn):
1.使用簡單既穆,代碼精簡赎懦。
2.解決了同時向多個對象監(jiān)聽相應(yīng)的問題。
3.傳值方便快捷幻工,Context自身攜帶相應(yīng)的內(nèi)容励两。
缺點(diǎn):
1.使用完畢后,要時刻記得注銷通知囊颅,否則將出現(xiàn)不可預(yù)見的crash当悔。
2.key不夠安全,編譯器不會監(jiān)測是否被通知中心正確處理踢代。
3.調(diào)試的時候動作的跟蹤將很難進(jìn)行盲憎。
4.當(dāng)使用者向通知中心發(fā)送通知的時候,并不能獲得任何反饋信息胳挎。
5.需要一個第三方的對象來做監(jiān)聽者與被監(jiān)聽者的中介饼疙。
3.Block(代碼塊)
Block是iOS4.0+ 和Mac OS X 10.6+ 引進(jìn)的對C語言的擴(kuò)展,用來實(shí)現(xiàn)匿名函數(shù)的特性
閉包是一個能夠訪問其他函數(shù)內(nèi)部變量的函數(shù)慕爬。
官方文檔中也提到了幾種Block的使用場合窑眯。
任務(wù)完成時回調(diào)處理
消息監(jiān)聽回調(diào)處理
錯誤回調(diào)處理
枚舉回調(diào)
視圖動畫屏积、變換
排序
優(yōu)點(diǎn):
1.語法簡潔,實(shí)現(xiàn)回調(diào)不需要顯示的調(diào)用方法磅甩,代碼更為緊湊炊林。
2.增強(qiáng)代碼的可讀性和可維護(hù)性。
3.配合GCD優(yōu)秀的解決多線程問題卷要。
缺點(diǎn):
1.Block中得代碼將自動進(jìn)行一次retain操作渣聚,容易造成內(nèi)存泄露。
2.Block內(nèi)默認(rèn)引用為強(qiáng)引用却妨,容易造成循環(huán)引用饵逐。
(二)注意事項
1.代理
在代理中調(diào)用方法的時候使用的是系統(tǒng)的子線程,因此彪标,當(dāng)使用Delegate進(jìn)行UI操作的時候,必須調(diào)用GCD的主線程方法:
dispatch_async(dispatch_get_main_queue(), <^(void)block>)掷豺,在block中寫進(jìn)行的UI操作代碼捞烟。
2.通知
在通知的使用過程中Crash的原因很多情況都是注冊觀察者以后沒有及時的注銷觀察者,當(dāng)然這個情況在非ARC時代比較常見当船,但是這并不是說在現(xiàn)在的ARC時代就不會出現(xiàn)這個問題题画。往往一旦出現(xiàn)問題就很難追查,所以還是要養(yǎng)成及時注銷的習(xí)慣德频。
由于通知的使用極其簡單苍息,往往能夠看到很多開發(fā)人員在開發(fā)過程中濫用NSNoticationCenter的現(xiàn)象。導(dǎo)致到處都是亂七八糟的通知壹置,代碼的可維護(hù)性和可讀性非常差竞思,即便是使用了宏定義也不能完全避免這些問題。比如在Debug的時候钞护,當(dāng)存在多個Observe的時候盖喷,簡直就是要人命的感覺,想死的心都有了难咕。在這方面Block和Delegate比Notification強(qiáng)太多了课梳。
3.Block
當(dāng)在Block中引用某個外部變量的時候,Block內(nèi)部只會進(jìn)行只讀拷貝余佃,這也就意味著暮刃,即便你在使用Block之前修改了那個外部變量的值,那么在你使用的Block里面它的值依舊是最開始的那個外部變量的值爆土。如果想要同步外部變量的值椭懊,那么就需要在block內(nèi)部引用變量時,在前面加上__block關(guān)鍵字雾消。
block本身是像對象一樣可以retain灾搏,和release挫望。但是,block在創(chuàng)建的時候狂窑,它的內(nèi)存是分配在棧(stack)上媳板,而不是在堆(heap)上。他本身的作于域是屬于創(chuàng)建時候的作用域泉哈,一旦在創(chuàng)建時候的作用域外面調(diào)用block將導(dǎo)致程序崩潰蛉幸。
(三)使用場景對比
1.回調(diào)方法
在日常的開發(fā)過程中,我們經(jīng)常會遇到一些完成之后的處理問題丛晦,比如完成網(wǎng)路請求之后的回調(diào)奕纫,或者頁面加載完成之后的回調(diào)等。這個時候我們一般使用的是前兩者方法烫沙,即Block或者Delegate匹层。
而在一對一傳輸回調(diào)的時候明顯Block的使用更加的簡單高效,只需要在代碼塊中執(zhí)行所需要的操作即可锌蓄。
在一對多的情況下升筏,Delegate更加能夠發(fā)揮出自己的優(yōu)勢。
2.跨層通信
有的時候我們需要實(shí)現(xiàn)在兩個毫無關(guān)聯(lián)的對象之間的通信瘸爽,這個時候如果使用Block或者Delegate就勢必會增加代碼的耦合性您访,這樣對于代碼的結(jié)構(gòu)來說是不健康的,因此這個時候使用Notification便是明智的選擇剪决。
3.UI響應(yīng)事件
用戶在與App的UI進(jìn)行互動的時候灵汪,總會需要App進(jìn)行交互響應(yīng),這個時候就毫無疑問的使用代理設(shè)計模式柑潦。而蘋果官方給出的建議也是可以肯定的享言,在Cocoa Touch框架中我們也可以在幾乎所有的UI交互控件的頭文件里看到Delegate的成員變量,也正是印證了在UI響應(yīng)事件上Delegate有著絕對的優(yōu)勢妒茬。
4.簡單值得傳遞
當(dāng)需要進(jìn)行簡單值得傳遞的時候担锤,比如子控件傳輸給父控件所點(diǎn)擊的IndexPath的時候,更加適合使用Block來傳值乍钻。因為肛循,如果只是為了傳這一個簡單的值而沒有特別的業(yè)務(wù)處理而定義一個協(xié)議,然后實(shí)現(xiàn)協(xié)議银择,設(shè)置代理再寫方法的話將十分麻煩多糠,得不償失,這個時候簡單高效的Block就可以完美的替代Delegate完成任務(wù)了浩考。