[譯]Swift利用協議優化NSNotificationCenter

發表於2016-06-05

原文:Swift: NSNotificationCenter protocol

NSNotificationCenter在OSX第一個版本釋出時就存在了,已經有超過17年的歷史,很多開發者已經對它很熟悉。它是設計模式中觀察者模式的一種實現。

NSNotificationCenter存在的問題

通知沒有統一的命名格式

對於通知的命名沒有強制的要求,一個專案裡可能有多種不同的命名規則。比如:

通知名稱可能衝突

因為對於通知名稱沒有限制,可能在不同的物件定義了同樣的通知名,這樣會導致難以意料的bug。

通知的名稱是字串

字串真的太危險了,很容易出現打錯的情況。

利用protocol的解決方案

我們通過設計一個protocol來解決上面提到的問題。

通過列舉統一通知名稱

給這個協議增加一個關聯型別:

所有要傳送通知的物件或者結構體都要實現Notifier這個協議,然後提供一個實現了RawRepresentable的型別。其實就是一個字串列舉。

這樣就可以有一個統一的方式獲取通知名稱:

避免通知名稱衝突

我們可以為通知新增一個唯一的名稱空間(namespace)來避免衝突。這裡想到的解決方案是使用實現這個協議的object名稱,因為每個object的名稱在一個專案裡是唯一的。

但是每個通知都要手動新增就太蛋疼了。我們給這個協議加一個擴充方法來生成唯一的通知名稱。因為這個方法只需要內部知道,所以標記為private。

Notifier的擴充套件方法

新增觀察者

最後一個通知的引數型別就是前面定義的那個列舉型別,這樣就不用輸入通知名稱的字串。

這樣在使用的時候,在實現協議的object上直接方便的新增觀察者:

傳送通知

呼叫的時候應該是這樣的:

這裡利用了swfit的預設引數,object和userinfo設定一個預設的空值。實現如下:

移除觀察

這個實現就不貼了。和前面兩個方法類似。呼叫的時候是這樣的:

總結

通過靈活利用swfit的語言特性:協議關聯型別,協議可以新增預設的方法實現以及方法的預設引數,利用自定義的Notifier協議封裝了NSNotificationCenter的呼叫方式,解決了傳統NSNotificationCenter呼叫的可能產生的三個潛在風險。

歡迎關注我的微博:@沒故事的卓同學
原始碼: https://github.com/andyyhope/Blog_NSNotificationCenterProtocol

相關文章