2013年4月20日 星期六

跨越種族(物件)之間的呼喊 - Notification

如果曾經有寫過 Objective - C 的話,對於這個名詞應該不陌生。在 iOS App 裡,Notification 是用來協助不同介面 or 功能之間的事件傳遞,而彼此不用知道對方的存在。C# 裡雖然已經有 Event 這種方式可以使用,但使用方便即彈性仍不如 Notification。而 Unity 中的 BroardcastMessage 也有效能和無法指定某元件的問題。

Notification 的運用層面很廣,不過還是先來講解如何架構 Nofication Center

參考資料:Uniti Wiki Notification Center

和參考資料所不同的是,我並沒有使用 SendMessage 去架構 Notification Center。考量到同一物件的不同元件註冊時可能接受到兩個以上的通知和效能上的問題,我改用了 Interface 的寫法。

Notification 的原理是

物件註冊通知訊息 -> 當有其他物件發出通知訊息 -> 註冊中的物件會接受到訊息

所以只要定義好訊息的功能是什麼,就可以依照不同的訊息來做不同的事

我們先從定義通知訊息的資料開始



發出通知時,我們必須要有

通知者 - 該通知是誰發出的
訊息 - 通知的訊息名稱
資料 - 通知所要傳遞的資料

有了這三項,接受通知者幾乎可以決定要利用什麼資料做什麼樣的事情

接下來,就是要建立一個機制去管理通知訊息和註冊物件
首先,我們需要定義一個 Interface 去決定接受通知的物件入口



所有使用通知機制的物件,都要繼承該介面
有了接口後,我們就可以決定如何管理訊息列表和註冊物件



程式碼看起來很長,但最主要是做四件事情

1.建立通知中心的 Singleton
2.註冊接受該訊息的物件
3.移除接受該訊息物件的註冊
4.發出通知

有這四個功能後,使用上就非常簡單

使用範例



把這兩個 Component 掛到物件上後

DoGameOver 會發出「儲存遊戲」通知,DoSaveGame 接受到 5 秒後發出「遊戲儲存完畢」通知,DoGameOver 接到「遊戲儲存完畢」後離開遊戲。



Notification 運用得好的話,在程式之間的合作也能獲得極大的助益

現實中的行為就會像是

A 負責寫「儲存遊戲」的功能,B 只要發出「儲存遊戲」的通知,A 接到通知後儲存完遊戲,再發出「儲存遊戲完畢」,B 等待「儲存遊戲完畢」的通知後,繼續做別的事情。程式們只要事先定好通知規則和資料即可。

3 則留言:

  1. 出現找不到型別或命名空間名稱 INotification ,請問遺漏了什麼
    謝謝

    回覆刪除
    回覆
    1. 你應該是少了 INotification 的定義宣告,上面有個「通知介面定義」短短三行,放在 NotificationCenter 定義宣告的上面就可以了

      刪除