10、無事勿擾,有事通知(1)——NSNotification

概述html

好久好久之前,有一隻菜鳥正在美滋滋的擼着他的嵌入式C代碼。然而有一天,老闆對菜鳥說:「別擼C了,從如今開始你就寫swift開發ios了。」菜鳥一臉懵逼,但仍是照作了。ios

又有一天,菜蛋諂媚的對菜鳥說:「個人左腳小拇指忽然發生了間歇性肌肉組織神經調控微紊亂,能不能幫忙拿個快遞?」菜鳥不屑道:「沒空!」swift

老闆和菜鳥的關係叫作「調用」,菜蛋和菜鳥的關係叫作「通知」。ide

所謂「通知」,就是當對象A發生了狀態變化時,它將該信息變化發送給對此感興趣的其餘對象,以便後者採起相應行爲。函數

「通知」相對於「調用」的優勢在於:在程序運行期間,被通知者能夠選擇性的接收甚至拒絕通知者的消息以及動態的修改相應的動做,而「調用」則不行。post

iOS存在2種實現通知的方式,一是KVO,二是NSNotification。這節咱們就先來講說NSNotification。spa

 

概念及流程3d

Notification:通知信號標誌,以「name」做爲其ID。code

NotificationCenter:通知信號標誌管理中心,負責維護和分發Notification及其攜帶的數據。server

使用流程以下(以下圖):

1. 首先建立1個NotificationCenter,而後使用該NotificationCenter的函數「addObserver」將Ob一、Ob二、Ob3和Notification:Name1進行綁定。

2. 當Sender想對Notification:Name1發送數據時,使用NotificationCenter的函數「post」將數據和Notification:Name1綁定發送。

3. NotificationCenter遍歷以前全部和Notification:Name1綁定過得Observer,並連帶Notification:Name1的數據調用各個Observer的回調函數。

 

舉個例子

紙上得來終覺淺,咱們先來實現個例子。

咱們建立3個label做爲Observer和1個button做爲Sender,3個label會監聽Notification消息,當接收到消息通知時,就打印收到的數據。button點擊後會觸發其發送消息。

 

 1 import UIKit
 2 
 3 class MyUILabel: UILabel {
 4 
 5     var say:String = "..."
 6     let userInfoKeyFly = "fly"
 7     let userInfoKeyHeight = "height"
 8     
 9     func setSay(say:String) {
10         self.say = say
11     }
12     
13     func addObserver(notificationName: Notification.Name) {
14         NotificationCenter.default.addObserver(self, selector: #selector(callback(notification: )), name: notificationName, object: nil)
15     }
16     
17     @objc func callback(notification: Notification) {
18         let userInfo = notification.userInfo as! [String:AnyObject]
19         let flyValue = userInfo[userInfoKeyFly] as! String
20         let heightValue = userInfo[userInfoKeyHeight] as! Int32
21         
22         text = "\(say)(\(flyValue):\(heightValue)米)"
23     }
24     
25     deinit {
26         NotificationCenter.default.removeObserver(self)
27     }
28 
29 }
View Code

首先,咱們自定義了Label,addObserver是其對外監聽消息的藉口,callback爲收到消息後的回調函數。此外還得添加析構函數deinit,以刪除其對消息的監聽,不然將發生內存泄漏。(注意:NotificationCenter.default是系統爲APP建立的默認NotificationCenter

 

 1 import UIKit
 2 
 3 
 4 class ViewController: UIViewController {
 5     
 6     @IBOutlet weak var passerby1: MyUILabel!
 7     @IBOutlet weak var passerby2: MyUILabel!
 8     @IBOutlet weak var passerby3: MyUILabel!
 9     
10     let notificationName = Notification.Name(rawValue: "noob")
11     let userInfoKeyFly = "fly"
12     let userInfoKeyFlyValue = "high"
13     let userInfoKeyHeight = "height"
14     let userInfoKeyHeightValue = 1
15 
16     override func viewDidLoad() {
17         super.viewDidLoad()
18         passerby1!.setSay(say: passerby1.text! + "我不信")
19         passerby2!.setSay(say: passerby2.text! + "我會信?")
20         passerby3!.setSay(say: passerby3.text! + "差點信了")
21         passerby1!.addObserver(notificationName: notificationName)
22         passerby2!.addObserver(notificationName: notificationName)
23         passerby3!.addObserver(notificationName: notificationName)
24         
25     }
26 
27     override func didReceiveMemoryWarning() {
28         super.didReceiveMemoryWarning()
29         // Dispose of any resources that can be recreated.
30     }
31 
32     @IBAction func flyHeighAction(_ sender: UIButton) {
33         NotificationCenter.default.post(name: notificationName, object: self, userInfo: [userInfoKeyFly:userInfoKeyFlyValue, userInfoKeyHeight:userInfoKeyHeightValue])
34         
35     }
36     
37 }
View Code

再ViewController中,咱們聲明瞭1個名爲「noob」的Notification,在viewDidLoad時,咱們使3個Label監聽了該Notification。flyHeightAction爲Button的觸摸回調函數,它會使用NotificationCenter.default向「noob」Notification發送數據userInfo(1個字典數據)。

 

若是有管理上的須要,咱們想建立本身的NotificationCenter,那麼只須要調用「NoficationCenter.init()」就能夠了,好比:

咱們經過擴展NotificationCenter來添加本身的NotificationCenter

1 extension NotificationCenter {
2     static let myNotificationCenter = NotificationCenter.init()
3 }

而後咱們就能夠將上例中的「default」都改成「myNotificationCenter」,獲得的結果是同樣的。

 

源碼下載:https://pan.baidu.com/s/1EdOhpwI-APUvedW5XlMrEw

 

上一節           回目錄          下一節 

相關文章
相關標籤/搜索