iOS中的通知(Notification)是一种广泛使用的通信机制,它允许不同组件、模块或应用程序间以一种松耦合的方式传递信息。通知机制的核心是NSNotificationCenter
(通知中心),它作为中介,负责发布(post)和分发(deliver)通知。下面详细阐述通知的原理及使用环境:
通知原理
发布者(Poster)与订阅者(Observer)
-
发布者:某个对象(通常是类实例)在特定时刻或条件满足时,向通知中心发送一条通知。通知通常包含一个唯一的名称(
NSString
对象,即通知名称或NSNotificationName
)、可选的用户信息(NSDictionary
对象,携带附加数据)。 -
订阅者:对特定通知感兴趣的对象通过向通知中心注册,成为该通知的订阅者。订阅者指定想要监听的通知名称,并提供一个回调方法(或一个实现了
observe(_:selector:name:object:)
方法的观察者对象),当通知中心接收到匹配的通知时,会调用订阅者的回调方法。
通知中心(NSNotificationCenter)
-
通知中心:系统提供的单例对象,负责协调发布者与订阅者之间的通信。它维护一个内部的数据结构(如映射表),存储订阅者与它们关注的通知之间的映射关系。
-
发布通知:发布者通过调用
NotificationCenter.default.post(name:object:userInfo:)
方法,将通知(包括名称、可选的关联对象和用户信息)发送给通知中心。 -
接收通知:订阅者通过以下两种方式之一注册监听:
-
使用Block回调:调用
NotificationCenter.default.addObserver(forName:object:queue:using:)
方法,传入一个闭包来处理接收到的通知。 -
使用Selector(方法)回调:调用
NotificationCenter.default.addObserver(_:selector:name:object:)
方法,传入订阅者对象(self)、要调用的方法(Selector)以及通知的名称和关联对象。
-
通知分发
- 通知分发:当通知中心收到发布者发送的通知后,它会查找已注册的订阅者列表,检查是否有订阅者对这条通知感兴趣。如果有匹配的订阅者,通知中心会按照注册时指定的队列(对于Block回调)或直接在订阅者所在的线程(对于Selector回调)上执行相应的回调,从而将通知信息传递给订阅者。
使用环境
通知在iOS开发中有多种应用场景,适用于以下情况:
跨组件通信
-
同一应用内:不同视图控制器、模型对象、服务类等组件间,当一个组件的状态变化需要告知其他组件但它们之间没有直接引用关系时,可以通过通知来解耦。
-
应用与框架/库之间:第三方库或系统框架(如UIKit、CoreData等)可能会通过通知来报告重要事件,应用程序可以订阅这些通知来响应框架的变化。
生命周期事件
-
系统事件:iOS系统会发送一系列全局通知,如应用进入后台、恢复前台、内存警告等,开发者可以通过监听这些通知来适配系统状态变化。
-
界面相关:如键盘弹出与隐藏、屏幕旋转等,通过监听相关通知可以调整UI布局或行为。
异步任务与数据更新
-
网络请求完成:在网络请求成功或失败后,发送通知告知UI或其他依赖数据的组件数据已更新,无需直接调用接口等待结果。
-
定时任务:定时器触发时发送通知,通知其他组件进行定时操作或数据刷新。
可撤销的操作
- 撤销/重做:在实现撤销/重做功能时,可以使用通知来同步撤销栈的状态,使得各相关组件能够及时响应撤销/重做操作。
注意事项
尽管通知机制简化了跨组件通信,但因其一对多的广播特性,需要注意以下几点:
-
性能影响:大量订阅者监听同一通知时,可能会对性能产生一定影响。因此,应合理使用通知,避免不必要的全局广播。
-
内存管理:订阅者需在适当的时候(如视图控制器的
deinit
方法中)调用removeObserver(_:name:object:)
方法注销监听,防止因订阅者提前释放导致的崩溃。 -
同步/异步:通知分发既可以同步(在发布者的线程上立即执行回调)也可以异步(在指定的队列上执行)。选择合适的分发方式以避免阻塞主线程或引发竞态条件。
综上所述,iOS中的通知机制基于发布/订阅模式,通过NSNotificationCenter
实现跨组件、跨层级的信息传递。它适用于各种需要解耦通信的场景,但在使用时需注意性能、内存管理和异步问题。