65-Swift 之 消息通知(Notification)

一、 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é)果

917BA22F-2AC5-406D-AA76-7C9225D2EC24.png
  • 在注冊消息通知時,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é)果

D9691BE1-3FA9-43CC-B9E8-948D34F0AF90.png
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é)果

9FEA9111-29A3-48FA-8411-06480B8CDE8B.png
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é)果

D9DF7B66-C983-448F-869D-028CBDDCEB51.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 在多數(shù)移動應(yīng)用中任何時候都只能有一個應(yīng)用程序處于活躍狀態(tài),如果其他應(yīng)用此刻發(fā)生了一些用戶感興趣的那么通過通知...
    莫離_焱閱讀 6,722評論 1 8
  • 轉(zhuǎn)載自南峰子的技術(shù)博客 一個NSNotificationCenter對象(通知中心)提供了在程序中廣播消息的機制,...
    我消失1314閱讀 979評論 0 2
  • NSNotificationCenter對象(通知中心)提供了在程序中廣播消息的機制,它實質(zhì)上就是一個通知分發(fā)表。...
    9de75b652cd9閱讀 801評論 0 1
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,666評論 30 472
  • 雨微涼,人獨立,亂花叢中,又見伊人倩影; 眼迷離,心憔悴,水色朦朧,不知佳人何處. 兀自佇立于雨中,既有期待又不作...
    夢星殺云閱讀 395評論 0 5

友情鏈接更多精彩內(nèi)容