以前的發(fā)送通知的參數(shù)就是一個簡單的字符串:
NSNotificationCenter.defaultCenter().post("someStringThatShouldBeDeclared")
后來到了swift 3 中,改成了Notification.Name。定義在Notification的命名空間下,是一個結(jié)構(gòu)體,初始化函數(shù)接收一個字符串。
extension NSNotification {
public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
public init(_ rawValue: String)
public init(rawValue: String)
}
}
用起來就麻煩了一點(diǎn):
NotificationCenter.default.post(Notification.Name(rawValue: "MyNotificationName"))
如果還是按照以前的方式定義一個全局字符串常量就沒有好好領(lǐng)會Swift精神了。
至少需要這樣,通過extension聲明一個靜態(tài)的常量:
extension Notification.Name {
static let AccountBalanceUpdated = Notification.Name("accountBalanceUpdated")
}
// invocation
NotificationCenter.default.post(.AccountBalanceUpdated)
但是這種方式有一個小缺點(diǎn),自定義的通知和系統(tǒng)的混在了一起,有時找起來比較尷尬。

這里其實(shí)也有另外一個問題,這種方式不能避免通知的名字重復(fù)。雖然如果命名規(guī)范不會有這樣的問題,但是到底是個潛在的風(fēng)險。
如果把上面兩個問題合起來看,就有了另外一種方式:利用Enum。
先聲明一個rawValue為字符串的枚舉。為了規(guī)避命名的沖突,聲明一個計算屬性,在每個值的rawValue前插入一個字符串。再用這個字符串去生成NSNotification.Name:
enum CPNotification: String {
case userLogout
case userLogin
var stringValue: String {
return "CP" + rawValue
}
var notificationName: NSNotification.Name {
return NSNotification.Name(stringValue)
}
}
用起來就簡單了,自己寫一個擴(kuò)展方法:
extension NotificationCenter {
static func post(customeNotification name: CPNotification, object: Any? = nil){
NotificationCenter.default.post(name: name.notificationName, object: object)
}
}
這樣在使用時,直接點(diǎn)出來的就都是自定義的通知了。
當(dāng)然在通知處理的地方也寫個擴(kuò)展方法用起來就更爽了,比如我用Rx所以這樣寫:
extension Reactive where Base: NotificationCenter {
func notification(custom name: CPNotification, object: AnyObject? = nil) -> Observable<Notification> {
return notification(name.notificationName, object: object)
}
}
用起來就是這樣:
// 發(fā)送通知
NotificationCenter.post(customeNotification: .userLogout)
// 接收通知
let _ = NotificationCenter.default.rx.notification(custom: .userLogout).subscribe(onNext: { (value) in
CPNetworkConfig.userID = nil
})
歡迎在社交網(wǎng)絡(luò)上關(guān)注我:
- 推特:@慶春路卓富貴
- 微博:@沒故事的卓同學(xué)