一、 Notification的介紹
Swift的消息通知機制(Notification)算是同步的,觀察者只要向消息中心注冊, 即可接受其他對象發(fā)送來的消息,消息發(fā)送者和消息接受者兩者可以互相一無所知,完全解耦。這種消息通知機制可以應(yīng)用于任意時間和任何對象,觀察者可以有多個,所以消息具有廣播的性質(zhì),只是需要注意的是,觀察者向消息中心注冊以后,在不需要接受消息時需要向消息中心注銷,屬于典型的觀察者模式。
二 、消息通知的兩個重要類
Notification : 是消息的載體。它可以攜帶一些信息給消息的接受者。通過它我們還可以獲取一些消息的一些基本信息。
NotificationCenter : 消息的控制中心??刂葡⒌淖?、發(fā)送、移除。
三 、Notification 的介紹
// MARK: Notification 的參數(shù)和方法介紹
func introduceNotification() -> Void {
// 由消息的名字創(chuàng)建消息
let notification = Notification.init(name: Notification.Name(rawValue: "NetWork小賤"))
// 消息協(xié)帶的數(shù)據(jù)
let address = "北京市朝陽區(qū)"
let persons = ["Z":"張飛","G":"宮本","X":"小喬"]
// 另一種創(chuàng)建消息的方式
let notificationOther = Notification.init(name: Notification.Name(rawValue:"NetWork小賤"), object: address, userInfo: persons)
// 消息的名字
print(notification.name)
// 獲取消息攜帶的對象信息
print(notificationOther.object!)
// 獲取消息攜帶的用戶數(shù)據(jù)信息
print(notificationOther.userInfo!)
// 獲取消息的描述
print(notificationOther.description)
// 獲取消息的哈希值
print(notificationOther.hashValue)
// 比較兩個消息是否相等
let IsEqual = notificationOther == notification
print(IsEqual)
}
四 、NotificationCenter 的介紹
// MARK: NotificationCenter 的介紹
func introduceNotificationCenter(){
// 創(chuàng)建一個對象
let DefaultNotification = NotificationCenter.default
// 注冊一個消息通知
DefaultNotification.addObserver(self, selector: #selector(notificationMethod(_:)), name: NSNotification.Name(rawValue: "NetWork小賤"), object: nil)
// 發(fā)送消息 1 ,不攜帶任何消息的消息發(fā)送
let notification = Notification.init(name: Notification.Name(rawValue: "NetWork小賤"))
DefaultNotification.post(notification)
// 發(fā)送消息 2 , 攜帶對象消息的消息發(fā)送
DefaultNotification.post(name: Notification.Name(rawValue: "NetWork小賤"), object: "成功QQ吧!")
// 發(fā)送消息 3 , 攜帶對象又?jǐn)y帶用戶信息的消息發(fā)送
DefaultNotification.post(name: Notification.Name(rawValue: "NetWork小賤"), object: "成功QQ吧", userInfo: ["Z":"張明","X":"嚇人"])
// 移除注冊的消息通知
DefaultNotification.removeObserver(self)
DefaultNotification.removeObserver(self, name: Notification.Name(rawValue: "NetWork小賤"), object: nil)
}
六、 消息的群發(fā)機制
- 在注冊消息通知時,name 不存在,object 存在的情況下,會接收所有 object 發(fā)出的通知。
// MARK: 消息通知機制的測試
func testNotification() -> Void {
let textField = UITextField.init()
NotificationCenter.default.addObserver(self, selector: #selector(methodNotification), name: nil, object: textField)
// 第一種
NotificationCenter.default.post(name: .UITextFieldTextDidEndEditing, object: textField)
// 第二種
NotificationCenter.default.post(name: .UITextFieldTextDidChange, object: textField)
// 第三種
NotificationCenter.default.post(name: .UITextFieldTextDidBeginEditing, object: textField)
}
func methodNotification() -> Void {
print("測試觸發(fā)標(biāo)記")
}
測試結(jié)果

- 在注冊消息通知時,name 和 object 不存在,會接收所有發(fā)出的通知。
// MARK: 消息通知機制的測試
func testAllNotification() -> Void {
let textField = UITextField.init()
NotificationCenter.default.addObserver(self, selector: #selector(methodAllNotification(_ :)), name: nil, object: nil)
NotificationCenter.default.post(name: .UITextFieldTextDidChange, object: nil)
NotificationCenter.default.post(Notification.init(name: .init("NetWork")))
NotificationCenter.default.post(name: .UITextFieldTextDidChange, object: textField)
NotificationCenter.default.post(name: .UIKeyboardDidHide, object: nil, userInfo: [:])
}
func methodAllNotification(_ notification:Notification) {
print("測試所有觸發(fā)消息的標(biāo)記")
print(notification)
}
- 在注冊消息通知時,name 存在 ,object 不存在,會接收所有name發(fā)出的通知。
// MARK: 消息機制的測試
func testNameNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(methodnameNotification), name: NSNotification.Name(rawValue: "NetWork"), object: nil)
NotificationCenter.default.post(Notification.init(name: NSNotification.Name(rawValue: "NetWork")))
NotificationCenter.default.post(name: .UIKeyboardDidHide, object: nil, userInfo: nil)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork"), object: "成功QQ吧", userInfo: [:])
}
func methodnameNotification() {
print("name 消息的測試")
}
七 、 消息機制的回調(diào)
open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Swift.Void) -> NSObjectProtocol
這個方法返回一個NSObjectProtocol 的對象,參數(shù)中并沒有指定具體的觀察者。實際上,與前一個方法不同的是,前者使用一個現(xiàn)存的對象作為觀察者,而這個方法會創(chuàng)建一個匿名的對象作為觀察者(即方法返回的NSObjectProtocol對象),這個匿名對象會在指定的隊列(queue)上去執(zhí)行我們的block。
1》上面函數(shù)參數(shù)的介紹
name : 消息的名字,也是一個標(biāo)示。
object : 消息觀察的對象,可為nil。
queue : 消息觀察所在的隊列,可為nil。如果為nil ,則回調(diào)將在發(fā)起消息的隊列線程中執(zhí)行。
block : 消息的回調(diào)。
注意: 在回調(diào)內(nèi)小心對象的循環(huán)引用。
2》消息的回調(diào)測試和使用
1、 queue 為nil的情況
// MARK: 消息的通知回調(diào)
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小賤"), object: nil, queue: nil) { (notif) in
print("接受的線程:" + "\(Thread.init())")
print("回調(diào)成功")
}
DispatchQueue.main.async {
print("發(fā)送的線程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小賤"), object: nil)
}
}
測試結(jié)果

2、queue 不為nil,發(fā)起消息不在同一個線程
// MARK: 消息的通知回調(diào)
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小賤"), object: nil, queue: OperationQueue.main) { (notif) in
print("接受的線程:" + "\(Thread.init())")
print("回調(diào)成功")
}
DispatchQueue.global().async {
print("發(fā)送的線程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小賤"), object: nil)
}
}
測試結(jié)果

3、 queue 不為nil,發(fā)起消息在同一個線程
// MARK: 消息的通知回調(diào)
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小賤"), object: nil, queue: OperationQueue.main) { (notif) in
print("接受的線程:" + "\(Thread.init())")
print("回調(diào)成功")
}
DispatchQueue.main.async {
print("發(fā)送的線程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小賤"), object: nil)
}
}
測試結(jié)果
