objective-c 委託的理解與應用

委託(delegate):

委託是一種設計模式。委託就是程序中的一個對象代替另一個對象來完成某些任務,或者是和另一個對象一起協調來完成某些工作。其中,委託者持有對被委託者的引用,並在適當地時間發送消息給被委託者。通過這個消息委託者通知被委託者自己將要處理或者是已經處理了某種事件。被委託者可以相應該消息,更新自己的或者是程序中的用戶界面或者是其他對象的狀態;並且還可以通過返回值來告知委託者自己對該事件的處理情況,以便委託者決策應該如何採取進一步的行爲。

委託和cocoa框架(delegation and cocoa framework)


在Cocoa框架中,委託者通常都是一個框架類的對象,而被委託者通常都是一個自定義的控制器對象。在需要進行內存管理的環境下,委託者都會持有對被委託者的一個弱引用;而在垃圾收集環境下,委託者持有對被委託者的強引用。在基礎庫中,UIKit,APPKit以及其他的Cocoa庫和Cocoa框架中,存在有大量委託的例子。

 

一個委託的例子就是AppKit框架中的NSWindow類的對象作爲委託者。NSWindow中聲明瞭一個協議(Protocol),其中有一個方法windowShouldClose:。當用戶點擊窗體上的關閉按鈕時,窗體對象就會發送windowShouldClose:消息給其委託(被委託者),詢問是否確認關閉該窗體。窗體的委託可以通過返回布爾類型的值來控制窗體對象的行爲。

如下圖:





窗體對象(委託者)                                                                                委託(被委託者)


委託與通知(Delegation and Notifications)


Cocoa框架中大多數類的委託都是自動地被註冊爲委託者發送的通知的觀察者。委託只需要實現在框架類中已經聲明瞭得通知方法來接收指定的通知消息即可。正如前面的示例一樣,窗體對象會發送NSWindowsWillCloseNotification消息給所有觀察者,但是隻會給其委託發送一個windowShouldClose:消息。


數據源(DataSource)


數據源幾乎和委託時等同的。區別在於他們和委託者的關係不同。數據源被委託是用來控制數據的,而不是處理用戶界面的。委託者,通常都是一個視圖對象,比如table 視圖,會持有其數據源的引用並根據需要向其請求需要顯示的數據。數據源,和委託類似,必需遵守一定的協議並實現協議中要求的最小的方法集。數據源要爲其委託者視圖的數據模型對象的內存管理負責。


通知(Notification)


通知是一種發送給一個或者多個觀察者,用來通知其在程序中發生了某個事件的消息。Cocoa中的通知機制遵循的是一種廣播的模式。它是一種程序中事件的發起者或者是處理者和其他想要知道該事件的對象溝通的一種方式。消息的接收者,也就是觀察者響應該事件來變換自己的UI,行爲或者是狀態。發送通知的對象沒有必要知道這些觀察者都是誰。因此,通知時一種在程序中可以獲得高效協作同時保持較高內聚性的機制。他減少了程序中對象相互之間的強依耐性(這種依耐性會大大降低程序中代碼的可複用性)。基礎庫,AppKit以及其他的一些Objective-C框架中的很多類都定義了通知以便我們可以註冊成爲通知的觀察者。

 

通知機制的核心就是一個進程中單一實例的對象,被叫做通知中心(NSNotificationCenter)。當一個對象發佈一個通知時,通知會先被髮布到通知中心。通知中心的作用相當於是交流所,作爲通知的廣播中心。程序中其他需要感知該事件的對象通過向通知中心註冊就可以達到在事件發生時被通知中心及時通知到得目的。通知中心是可以以同步的方式向其觀察者發送通知,也是可以通過使用通知隊列(NSNotificationQueue)來異步地發送通知。

 





用於表示通知的對象


一個通知是用NSNotification類的一個對象來表示的。表示通知的對象中含有用於表示該通知的信息的字段:通知的名稱,發佈通知的對象以及一個用於表示其他補充信息的字典。這個字典被稱爲是userInfo字典。當通知被髮送給對其感興趣的觀察者時,該表示通知的對象會被作爲參數傳入到處理該通知的方法中。


觀察指定的通知


實現觀察某個通知的時候,我們先要獲取NSNotificationCenter的單實例對象並向其發送addObserver:selector:name:object:消息。通常情況下,這種註冊的行爲在應用程序啓動後就要進行。addObserver:selector:name:object:方法的第二個參數是一個選擇器,該選擇器指定的是處理指定通知的具體方法。方法的原型必需如下:

-(void)myNotificationHandler:(NSNotification*)notif;

在該方法中,我們可以提取通知中的相關信息來幫助我們處理數據,特別是userInfo中的數據(如果userInfo存在的話)。


發佈通知


通常在發佈通知之前,我們都需要定義一個全局的字符串常量來作爲通知的名稱。傳統的做法是採用和應用程序相關的兩個或者三個字母作爲通知名稱的前綴,例如:

NSString & AMMyNotification = @”AMMyNotification”;

通過向NSNotificationCenter的單實例對象發送postNotificationName:object:userInfo:(或者類似的)消息來完成通知的發佈。在向通知中心發送通知之前,該方法會先創建一個表示該通知的對象。


委託機制原文:https://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html

通知機制原文:https://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/Notification.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章