iOS 中通知机制详解
NSNotification 通知的对象,一条通知就是一个NSNotification对象,包含如下属性:
@property (readonly, copy) NSNotificationName name;
@property (nullable, readonly, retain) id object;
@property (nullable, readonly, copy) NSDictionary *userInfo;
NSNotificationCenter 管理通知的类,负责添加,发送,移除通知
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
关于name和object
- name为空,接收所有通知
- name不空,添加通知的object空,仍然接收所有name相同的通知
- name不空,添加通知object不空,接收name和object都匹配的通知
- 发送通知的时候,是否指定object对接收者不影响
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;
移除通知,iOS8之前需要手动移除通知,iOS8之后系统会在dealloc调用时,执行removeObserver移除所有通知
NSNotificationQueue 通知队列,根据发送和合并策略,发送通知
- 添加通知到队列
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray<NSRunLoopMode> *)modes;
- 从队列移除通知
- (void)dequeueNotificationsMatching:(NSNotification *)notification coalesceMask:(NSUInteger)coalesceMask;
关于通知队列的两个策略:
- 何时发送
typedef NS_ENUM(NSUInteger, NSPostingStyle) {
NSPostWhenIdle = 1,//空闲时
NSPostASAP = 2,//尽可能快
NSPostNow = 3//立刻
};
- 怎样合并
typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {
NSNotificationNoCoalescing = 0,//从不
NSNotificationCoalescingOnName = 1,//name 相同的合并
NSNotificationCoalescingOnSender = 2//sender相同的合并
};
asap和whenIdle需要开启当前runloop,并处在添加时的runLoopMode下
-
通知是同步还是异步;
主线程中通知是同步,会等待处理通知的代码执行完才执行后面的代码
子线程中发送通知,响应通知的代码会在它发出通知的线程中执行,所以是异步的
如果想在子线程发送通知,主线程响应通知就需要手动回调到主线程执行。