一、什么是通知
通知 是 iOS 中实现 一对多 通信的核心机制,基于观察者模式设计。当某个事件发生时,发布者(Publisher)通过 NotificationCenter 向所有订阅者(Subscriber)广播通知,实现组件间的解耦通信。
二、核心组件
- NotificationCenter
系统提供的单例,负责管理通知的注册、发送和分发。
// 获取默认的通知中心
let center = NotificationCenter.default
- Notification
通知对象,包含通知的名称、发送者和用户信息。
// 创建通知
let notification = Notification(
name: .myCustomNotification, // 通知名称
object: self, // 发送者
userInfo: ["key": "value"] // 附加信息
)
- Notification.Name
通知名称,用于标识不同类型的通知。
// 定义通知名称扩展
extension Notification.Name {
static let myCustomNotification = Notification.Name("MyCustomNotification")
}
三、使用步骤
步骤 1:定义通知名称
// 在 Notification.Name 扩展中定义
extension Notification.Name {
static let networkStatusChanged = Notification.Name("NetworkStatusChanged")
static let videoPlaybackStateChanged = Notification.Name("VideoPlaybackStateChanged")
}
步骤 2:订阅通知
class MyViewController: UIViewController {
var observer: NSObjectProtocol? // 保存观察者引用
override func viewDidLoad() {
super.viewDidLoad()
// 方式 1:使用 selector(Objective-C 风格)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleNetworkChange(_:)),
name: .networkStatusChanged,
object: nil // nil 表示接收任何发送者的通知
)
// 方式 2:使用闭包(Swift 风格)
// 使用闭包时,使用 [weak self] 避免循环引用
observer = NotificationCenter.default.addObserver(
forName: .videoPlaybackStateChanged,
object: nil,
queue: .main // 指定执行队列
) { [weak self] notification in
self?.handlePlaybackChange(notification)
}
}
@objc func handleNetworkChange(_ notification: Notification) {
// 处理网络状态变化
if let isConnected = notification.userInfo?["isConnected"] as? Bool {
print("网络状态: \(isConnected)")
}
}
func handlePlaybackChange(_ notification: Notification) {
// 处理播放状态变化
if let state = notification.userInfo?["state"] as? String {
print("播放状态: \(state)")
}
}
deinit {
// 必须取消注册
NotificationCenter.default.removeObserver(self)
// 如果使用闭包方式,需要移除特定的 observer
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
步骤 3:发送通知
// 发送通知
NotificationCenter.default.post(
name: .networkStatusChanged,
object: self, // 发送者
userInfo: ["isConnected": isConnected] // 附加信息
)
步骤 4:取消订阅
// 方式 1:移除所有观察者
deinit {
NotificationCenter.default.removeObserver(self)
}
// 方式 2:移除特定通知的观察者
deinit {
NotificationCenter.default.removeObserver(self, name: . networkStatusChanged, object: nil)
}
// 方式 3:移除特定发送者的观察者
deinit {
NotificationCenter.default.removeObserver(self, name: nil, object: sender)
}
// 方式 4:如果使用闭包方式,需要移除特定的 observer
deinit {
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
四、总结
通知模式的核心要点 :
- 一对多通信 :一个发布者通知多个订阅者
- 解耦设计 :发布者和订阅者不需要知道彼此
- 弱引用机制 :默认不会导致循环引用
- 需要手动取消注册 :在 deinit 中移除观察者
适用场景 :
- 全局状态变化通知(如网络状态、登录状态)
- 跨模块通信(如 AppDelegate 通知各个 ViewController)
- 系统事件监听(如键盘弹出、内存警告)
与代理模式的选择 :
- 需要一对一通信或强类型检查 → 使用代理模式
- 需要一对多通信或跨模块广播 → 使用通知模式