Just My Life & My Work

學寫iOS App已經滿三年,回想那時候還是iOS 6,而如今再過兩個月就要邁入iOS 9,這個作業系統隨著時間持續進化,多數基礎機制沿用至今。儘管已會獨立寫出一個App,然而在Objective C技術上還是有待精進,比如用來傳遞訊息或資料的溝通模式 (Communication Patterns),我也僅熟悉某幾種,其機制的概念與優劣尚未明朗,於是想趁著昌鴻颱風給放假的時候,來瞭解一下這五種溝通模式:

  • KVO (Key-Value Observing)
  • Notifications
  • Delegation
  • Blocks
  • Target-Action

Communication Patterns

來個關鍵問題,為何程式需要溝通?

這好比人是群居動物需要溝通,當然你也可以一個人獨自生活,只是會過得非常辛苦,因為什麼芝麻小事都要自己來做;

而寫程式有著類似的道理,你當然可以把所有程式碼寫在同一個檔案裡,那就不用跟其它檔案溝通,不過這在大型專案卻不怎個管用,因為你需要開發許多功能,而且日後也要持續維護、修改、除錯,如果我們將各個主要功能分別寫在不同的檔案中,那麼未來一下子就可以找到目標檔案,此時也能給專案夥伴幫忙修改、除錯、維護。於是乎,溝通的方式就顯得非常重要。

先說這些模式沒有一定的優劣,端視專案的需求來選擇,如想要快速開發,如想要方便維護,如想要安全可靠等等。透過閱讀前人文章後記錄下自己覺得一定要知曉的概念,參考了英語、簡中文章,現在把它轉化成繁中。

接著來了解五種溝通模式 (Communication Patterns)

1、KVO – Key-Value Observing(鍵-值觀察)

  • KVO機制用於通知對象屬性的變化。
  • 消息接收者->接收對象屬性變化的消息;消息發送者->對象屬性發生變化。
  • 消息接收者透過註冊對消息發送者的監聽,還必須知道消息發送者的生命期,用以解除對其的註冊。

2、Notifications(通知)

  • Notifications用於在程式碼間廣播消息。
  • Notifications發送的消息是任意的,你可以透過userInfo字典或者用NSNotification消息載體裝載發送的消息。
  • 透過Notifications,消息發送者消息接收者可以互不認識,即在鬆耦合的程式碼間傳遞消息。此外,這是一種單向的溝通方式,也就是說接收者不能回覆Notifications的消息通知。

3、Delegation(委託)

  • 委託的作用:傳值;傳事件。
  • 在委託協議中定義任意需要的委託方法處理兩個特定對象之間的溝通。消息發送者即委託者,在委託協議中定義委託方法,消息接收者即被委託者,實現委託協議中的委託方法。

4、Blocks(區塊)

  • Blocks通常用於回調事件處理等等,是一種相對較新的技術。一般情況下,block可以滿足用delegation實現的消息傳遞機制,不過這兩種機制還是有各自的特色。
  • 潛在的風險:retain cycle。由於被blocks引用的變數都會被自動retain一次,如果不能保證被引用的變數為nil,那麼使用Blocks就會出現retain cycles。

舉個例子:

DoSomethingManager *manager = [[DoSomethingManager alloc] init];
manager.complete = ^{
    //...complete actions
    [manager otherAction];
    [manager release];
};

此例子中,由於manager和block相互持有,那麼即使調用了release,還是會形成retain cycle。

為了解除retain cycle,那麼程式碼修​​改為:

DoSomethingManager *manager = [[DoSomethingManager alloc] init];
manager.complete = ^{
    //...complete actions
    [manager otherAction];
    manager.complete = nil;
    [manager release];
};

由於這行程式碼manager.complete = nil,如此就破壞了retain cycle。

再看一個NSOperation的例子:

self.queue = [[NSOperationQueue alloc] init];
MyOperation *operation = [[MyOperation alloc] init];
operation.completionBlock = ^{
    [self finishedOperation];
};
[self.queue addOperation:operation];

乍看之下,似乎存在一個retain cycle:self~retain->queue~retain->operation~retain->blcok~retain->self
然而,一個operation添加到queue後,必定會在某一個時刻執行結束,然後退出queue,那麼一旦operation退出queue後,retain cycle也就被打破了。

5、Target-Action(目標-動作)

  • Target-Action是用來響應UI界面事件發送消息的典型模式。
  • 即使消息響應的target為nil,action也會沿著responder chain(響應鏈)找到一個對象來進行響應。
  • Target-Action的限制是消息發送不能攜帶任何自定義的負載消息。

我較為常用的是Notification、Delegation、Target-Action,使用第三方套件時常會發現其使用Block,而我比較不熟悉的是KVO,看了其描述後,我才發現自己不知不覺就用到KVO:P~

模式決策流程

基於上述溝通模式的特點,構建如下的流程圖,有助於在選擇哪種模式做出正確的決定,這張圖的建議並不一定是最終的答案,端視專案需求。

communication-patterns-flow-chart

參考:

Comments on: "[Objective C] 溝通模式 (Communication Patterns)" (1)

  1. […] 概念詳情可參考溝通模式 (Communication Patterns)。 […]

隨意留個言吧:)~

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲