第23條:通過委托與數據源協議進行對象間通信
第4章:協議與分類
Objective-C 語言有一項特性叫做“協議”(protocol),它與 Jave 的 “接口”(interface)類似。Objective-C 不支持多重繼承,因而我們把某個類應該實現的一系列方法定義在協議裏面。協議最為常見的用途是實現委托模式,不過也有其他用法。理解並善用協議可令代碼變得更易維護,因為協議這種方式能很好的描述接口。
“分類”(category)也是 Objective-C 的一項重要語言特性。利用分類機制,我們無須繼承子類即可直接為當前類添加方法,而在其他編程語言中,則需通過繼承子類來實現。由於 Objective-C 運行期系統是高度動態的,所以才能支持這一特性,然而,其中隱藏者一些陷阱,因此在使用分類之前,應該先理解它。
對象之間經常需要相互通信,而通信方式有很多種。Objective-C 開發者廣泛使用一種名叫“委托模式”(Delegate pattern)的編程設計模式來實現對象間的通信,該模式的主旨是:定義一套接口,某對象若想接受另一個對象的委托,則需遵從此接口,以便成為其 “委托對象”(delegate)。而這 “另一個對象” 則可以給其委托對回傳一些信息,也可以在發生相關事件時通知委托對象。
此模式可以將數據與業務邏輯解藕。比方說,用戶界面裏有個顯示一系列數據所用的視圖,那麽,此視圖只應包含顯示數據所需的邏輯代碼,而不應決定要顯示何種數據以及數據之間如何交互等問題。視圖對象的屬性中,可以包含負責數據與事件處理的對象。這兩種對象分別稱為“數據源”(data source)與 “委托”(delegate)。
在 Objective-C 中,一般通過 “協議” 這項語言特性來實現此模式,整個 Cocoa 系統框架都是這麽做的。如果你的代碼也這樣做。如果你的代碼也這樣寫,那麽就能和系統框架很好地融合在一起了。
為演示此模式,我們舉個例子,假設要編寫一個從網上獲取數據的類。此類也許要從遠程服務器的某個資源裏獲取數據。那個遠程服務器可能過很長時間才會應答,而在獲取數據的過程中阻塞應用程序則是一種非常糟糕的做法。於是,在這種情況下,我們通常會使用委托模式:獲取網絡數據的類含有一個“委托對象”,在獲取完數據之後,它會回調這個委托對象。圖演示了此概念:EOCDataModel 對象就是 EOCNetworkFetcher 的委托對象。EOCDataModel 請求 EOCNetworkFetcher “以異步方式執行一項任務”(perform a task asynchronously),而 EOCNetworkFetcher 在執行完這項任務之後,就會通知其委托對象,也就是 EOCDataModel。
利用協議機制,很容易就能以 Objective-C 代碼實現此模式。圖演示的這種情況下,協議可以這樣來定義:
第23條:通過委托與數據源協議進行對象間通信