iOS開發Delegate,Notification,Block使用心得

(一)簡要介紹

1.Delegate(代理、委託) 代理幾乎是iOS開發中最經常使用的傳值方式,在項目中的AppDelegate就是使用的這種設計模式,不只如此,還有不少原生的控件也使用的這種設計模式,好比:UITextFiled,UITableView等等。官方給出的解釋以下:html

Delegation is a simple and powerful pattern in which one object in a program 1 acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.ios

具體使用方法再也不示例(網上關於Delegate基礎使用的博文數不勝數示例),主要總結一下Delegate的優勢和缺陷。設計模式

優勢: 1.減小代碼的耦合性,使事件監聽和事件處理相分離。 2.清晰的語法定義,減小維護成本,較強的代碼可讀性。 3.不須要建立第三方來監聽事件和傳輸數據。 4.一個控制器能夠實現多個代理,知足自定義開發需求,可選必選有較大的靈活性。安全

缺點: 1.實現委託的代碼過程比較繁瑣。 2.當實現跨層傳值監聽的時候將加大代碼的耦合性,而且程序的層次結構將變的混亂。 3.當對多個對象同時傳值響應的時候,委託的易用性將大大下降。多線程

2.NotificationCenter(通知) 通知也是iOS開發中經常使用的一種傳值響應方法,例如在AVFoundation框架中的MPMoviePlayerController在監聽播放狀態改變,播放中止等事件時使用的也正是NotificationCenter。官方給出的解釋以下:閉包

An NSNotificationCenter object (or simply, notification center) provides a mechanism for broadcasting information within a program. An NSNotificationCenter object is essentially a notification dispatch table.架構

Objects register with a notification center to receive notifications (NSNotification objects) using the addObserver:selector:name:object: or addObserverForName:object:queue:usingBlock: methods. Each invocation of this method specifies a set of notifications. Therefore, objects may register as observers of different notification sets by calling these methods several times.app

Each running Cocoa program has a default notification center. You typically don’t create your own. An NSNotificationCenter object can deliver notifications only within a single program. If you want to post a notification to other processes or receive notifications from other processes, use an instance of NSDistributedNotificationCenter.框架

NSNotification採用的單例設計模式,當給通知中心註冊一個key之後,那麼不管在什麼地方只要給通知中心發送一個這個key的消息,那麼就實現了通訊傳值,註冊的通知的對象就會調用相應的方法。async

優勢: 1.使用簡單,代碼精簡。 2.解決了同時向多個對象監聽相應的問題。 3.傳值方便快捷,Context自身攜帶相應的內容。 缺點: 1.使用完畢後,要時刻記得註銷通知,不然將出現不可預見的crash。 2.key不夠安全,編譯器不會監測是否被通知中心正確處理。 3.調試的時候動做的跟蹤將很難進行。 4.當使用者向通知中心發送通知的時候,並不能得到任何反饋信息。 5.須要一個第三方的對象來作監聽者與被監聽者的中介。

3.Block(代碼塊) Block是iOS4.0+ 和Mac OS X 10.6+ 引進的對C語言的擴展,用來實現匿名函數的特性。蘋果官方對於Block的解釋也是十分的簡潔:

A block is an anonymous inline collection of code, and sometimes also called a 「closure」.Blocks are a powerful C-language feature that is part of Cocoa application development. They are similar to 「closures」 and 「lambdas」 you may find in scripting and programming languages such as Ruby, Python, and Lisp. Although the syntax and storage details of blocks might at first glance seem cryptic, you’ll find that it’s actually quite easy to incorporate blocks into your projects’ code.

翻譯過來就是,閉包是一個可以訪問其餘函數內部變量的函數。Block的使用在這裏也不在贅述(不知道的同窗能夠點這個連接,我以爲寫的很詳細)。不管是原生的框架仍是第三方的框架,咱們均可以看到Block的身影,Block強大的功能性和易用性使得深受架構師的喜好。

官方也有一篇簡短的指導文檔,有興趣的同窗能夠看一下(官方指導)。值得注意的是,在這份文檔中也提到了幾種Block的使用場合。

  • 任務完成時回調處理
  • 消息監聽回調處理
  • 錯誤回調處理
  • 枚舉回調
  • 視圖動畫、變換
  • 排序

優勢: 1.語法簡潔,實現回調不須要顯示的調用方法,代碼更爲緊湊。 2.加強代碼的可讀性和可維護性。 3.配合GCD優秀的解決多線程問題。

缺點: 1.Block中得代碼將自動進行一次retain操做,容易形成內存泄露。 2.Block內默認引用爲強引用,容易形成循環引用。

(二)注意事項

1.代理

  • 在代理中調用方法的時候使用的是系統的子線程,所以,當使用Delegate進行UI操做的時候,必須調用GCD的主線程方法: dispatch_async(dispatch_get_main_queue(), <^(void)block>),在block中寫進行的UI操做代碼。

2.通知

  • 在通知的使用過程當中Crash的緣由不少狀況都是註冊觀察者之後沒有及時的註銷觀察者,固然這個狀況在非ARC時代比較常見,可是這並非說在如今的ARC時代就不會出現這個問題。每每一旦出現問題就很難追查,因此仍是要養成及時註銷的習慣。
  • 因爲通知的使用極其簡單,每每可以看到不少開發人員在開發過程當中濫用NSNoticationCenter的現象。致使處處都是亂七八糟的通知,代碼的可維護性和可讀性很是差,即使是使用了宏定義也不能徹底避免這些問題。好比在Debug的時候,當存在多個Observe的時候,簡直就是要人命的感受,想死的心都有了。在這方面Block和Delegate比Notification強太多了。

3.Block

  • 當在Block中引用某個外部變量的時候,Block內部只會進行只讀拷貝,這也就意味着,即使你在使用Block以前修改了那個外部變量的值,那麼在你使用的Block裏面它的值依舊是最開始的那個外部變量的值。若是想要同步外部變量的值,那麼就須要在block內部引用變量時,在前面加上__block關鍵字。
  • block自己是像對象同樣能夠retain,和release。可是,block在建立的時候,它的內存是分配在棧(stack)上,而不是在堆(heap)上。他自己的做於域是屬於建立時候的做用域,一旦在建立時候的做用域外面調用block將致使程序崩潰。

(三)使用場景對比

1.回調方法 在平常的開發過程當中,咱們常常會遇到一些完成以後的處理問題,好比完成網路請求以後的回調,或者頁面加載完成以後的回調等。這個時候咱們通常使用的是前二者方法,即Block或者Delegate。而在一對一傳輸回 調的時候明顯Block的使用更加的簡單高效,只須要在代碼塊中執行所須要的操做便可。在一對多的狀況下,Delegate更加可以發揮出本身的優點。

2.跨層通訊 有的時候咱們須要實如今兩個毫無關聯的對象之間的通訊,這個時候若是使用Block或者Delegate就勢必會增長代碼的耦合性,這樣對於代碼的結構來講是不健康的,所以這個時候使用Notification即是明智的選擇。

3.UI響應事件 用戶在於App的UI進行互動的時候,總會須要App進行交互響應,這個時候就毫無疑問的使用代理設計模式。而蘋果官方給出的建議也是能夠確定的,在Cocoa Touch框架中咱們也能夠在幾乎全部的UI交互控件的頭文件裏看到Delegate的成員變量,也正是印證了在UI響應事件上Delegate有着絕對的優點。

4.簡單值得傳遞 當須要進行簡單值得傳遞的時候,好比子控件傳輸給父控件所點擊的IndexPath的時候,更加適合使用Block來傳值。由於,若是隻是爲了傳這一個簡單的值而沒有特別的業務處理而定義一個協議,而後實現協議,設置代理再寫方法的話將十分麻煩,得不償失,這個時候簡單高效的Block就能夠完美的替代Delegate完成任務了。

相關文章
相關標籤/搜索