一、 Notification的介绍
Swift的消息通知机制(Notification)算是同步的,观察者只要向消息中心注册, 即可接受其他对象发送来的消息,消息发送者和消息接受者两者可以互相一无所知,完全解耦。这种消息通知机制可以应用于任意时间和任何对象,观察者可以有多个,所以消息具有广播的性质,只是需要注意的是,观察者向消息中心注册以后,在不需要接受消息时需要向消息中心注销,属于典型的观察者模式。
二 、消息通知的两个重要类
-
Notification : 是消息的载体。它可以携带一些信息给消息的接受者。通过它我们还可以获取一些消息的一些基本信息。
-
NotificationCenter : 消息的控制中心。控制消息的注册、发送、移除。
三 、Notification 的介绍
// MARK: Notification 的参数和方法介绍
func introduceNotification() -> Void {
// 由消息的名字创建消息
let notification = Notification.init(name: Notification.Name(rawValue: "NetWork小贱"))
// 消息协带的数据
let address = "北京市朝阳区"
let persons = ["Z":"张飞","G":"宫本","X":"小乔"]
// 另一种创建消息的方式
let notificationOther = Notification.init(name: Notification.Name(rawValue:"NetWork小贱"), object: address, userInfo: persons)
// 消息的名字
print(notification.name)
// 获取消息携带的对象信息
print(notificationOther.object!)
// 获取消息携带的用户数据信息
print(notificationOther.userInfo!)
// 获取消息的描述
print(notificationOther.description)
// 获取消息的哈希值
print(notificationOther.hashValue)
// 比较两个消息是否相等
let IsEqual = notificationOther == notification
print(IsEqual)
}
四 、NotificationCenter 的介绍
// MARK: NotificationCenter 的介绍
func introduceNotificationCenter(){
// 创建一个对象
let DefaultNotification = NotificationCenter.default
// 注册一个消息通知
DefaultNotification.addObserver(self, selector: #selector(notificationMethod(_:)), name: NSNotification.Name(rawValue: "NetWork小贱"), object: nil)
// 发送消息 1 ,不携带任何消息的消息发送
let notification = Notification.init(name: Notification.Name(rawValue: "NetWork小贱"))
DefaultNotification.post(notification)
// 发送消息 2 , 携带对象消息的消息发送
DefaultNotification.post(name: Notification.Name(rawValue: "NetWork小贱"), object: "成功QQ吧!")
// 发送消息 3 , 携带对象又携带用户信息的消息发送
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)
}
六、 消息的群发机制
- 在注册消息通知时,name 不存在,object 存在的情况下,会接收所有 object 发出的通知。
// 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("测试触发标记")
}
测试结果
917BA22F-2AC5-406D-AA76-7C9225D2EC24.png- 在注册消息通知时,name 和 object 不存在,会接收所有发出的通知。
// 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("测试所有触发消息的标记")
print(notification)
}
- 在注册消息通知时,name 存在 ,object 不存在,会接收所有name发出的通知。
// 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 消息的测试")
}
七 、 消息机制的回调
open func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Swift.Void) -> NSObjectProtocol
这个方法返回一个NSObjectProtocol 的对象,参数中并没有指定具体的观察者。实际上,与前一个方法不同的是,前者使用一个现存的对象作为观察者,而这个方法会创建一个匿名的对象作为观察者(即方法返回的NSObjectProtocol对象),这个匿名对象会在指定的队列(queue)上去执行我们的block。
1》上面函数参数的介绍
-
name : 消息的名字,也是一个标示。
-
object : 消息观察的对象,可为nil。
-
queue : 消息观察所在的队列,可为nil。如果为nil ,则回调将在发起消息的队列线程中执行。
-
block : 消息的回调。
注意: 在回调内小心对象的循环引用。
2》消息的回调测试和使用
1、 queue 为nil的情况
// MARK: 消息的通知回调
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小贱"), object: nil, queue: nil) { (notif) in
print("接受的线程:" + "\(Thread.init())")
print("回调成功")
}
DispatchQueue.main.async {
print("发送的线程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小贱"), object: nil)
}
}
测试结果
D9691BE1-3FA9-43CC-B9E8-948D34F0AF90.png2、queue 不为nil,发起消息不在同一个线程
// MARK: 消息的通知回调
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小贱"), object: nil, queue: OperationQueue.main) { (notif) in
print("接受的线程:" + "\(Thread.init())")
print("回调成功")
}
DispatchQueue.global().async {
print("发送的线程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小贱"), object: nil)
}
}
测试结果
9FEA9111-29A3-48FA-8411-06480B8CDE8B.png3、 queue 不为nil,发起消息在同一个线程
// MARK: 消息的通知回调
func callBackNotification() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "NetWork小贱"), object: nil, queue: OperationQueue.main) { (notif) in
print("接受的线程:" + "\(Thread.init())")
print("回调成功")
}
DispatchQueue.main.async {
print("发送的线程:" + "\(Thread.init())")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NetWork小贱"), object: nil)
}
}
测试结果
D9DF7B66-C983-448F-869D-028CBDDCEB51.png
网友评论