一、 涉及的概念
涉及的概念:事件,消息,消息中心,监听者,消息发送者
二、 基本流程:
路线一:
1.消息中心登记监听者及其需要监听的消息(也叫注册监听者)。
2.消息发送者发送消息。
3.消息中心向所有已登记的监听者广播此消息。
路线二:
1.消息中心登记监听者及其需要监听的消息(也叫注册监听者)。
2.发送者将消息添加到消息队列,消息队列将类似的消息按一定规则集中起来再送达消息中心。
3.消息中心向所有已登记的监听者广播此消息。
其中,两条路线的第三步都是有系统类完成,我们要做的仅仅是第一步和第二步。
三、 涉及的概念对应的类
1. NSNotification(消息)
组成:name(通知的标识,通常定义成常量)、object(消息的发送者)、可选的dictionary(包含了有关事件的信息)
要从消息中提取有关事件的信息,至少要知道消息的name,以及Dictionary的对应的key。
2. NSNotificationCenter(消息中心)
在一个进程中使用的消息中心遵守单例模式,通过[NSNotificationCenter defaultCenter]来获得默认的消息中心。
要在多个进程中进行信息交换,使用NSDistributionNotificationCenter。每个应用进程都分配了一个默认的消息中心用来和其他进程通信,这个默认的消息中心通过[NSDistributedNotificationCenter defaultCenter]来获得。(不是本文重点)
默认情况下,事件的发生与事件的消息同步。也就是说,一旦某事件发生,消息发送者就会马上通过消息中心来给所有登记了的对象(事件监听者)发送消息,并且会等所有的监听者都处理完该消息后,消息发送者才重新获得控制。
如果需要异步发送消息,就要使用消息队列。
3. NSNotificationQueue(消息队列)
它负责两个重要的功能:消息的异步处理、消息的联合。
(1)消息的异步处理:
发送者不需要等消息得到监控者处理,并返回之后才能重新得到控制。只要在消息加入消息队列后返回,就能重新得到控制。
消息队列何时会发送其中的消息到消息中心由发送模式决定,并且可以通过设定run loop mode来限制消息队列在什么运行状态(mode)下发送消息。
三种发送模式(posting style):
-越快越好
NSPostASAP,一旦进入指定的运行状态就会把消息发送到消息中心,如果当前已经处于指定的运行状态下,那么在本次循环结束以后就会立即发送消息。
-空闲时发送
NSPostWhenIdle ,当用户没有处在输入状态,程序中没有其他异步事件发生的时候发送。比如,要根据用户输入内容长度来更新输入框的大小,就要监视用户输入这个事件,如果每输入一个字符就发送一次通知,这样太频繁,可以只在用户已经停止输入时才发送一次消息(其实是消息队列把多个消息联合起来一次发送)。
-即时发送
NSPostNow,和同步发送一样需要等到监视者返回后才重新获得控制,但是会先按联合模式对消息进行联合后再发送。????待验证
(2)消息的联合
对于重复发生的事件只进行一次通知,就是消息的联合。
联合也分三种模式(coalesceMask):
-不联合
NSNotificationNoCoalescing
-按名字联合消息
NSNotificationCoalescingOnName
同名就联合
-按消息发送者联合
NSNotificationCoalescingOnSender
同发送者就联合
(3)设定消息队列的异步处理模式、联合模式
设定消息队列的异步处理模式、联合模式是在将消息加入队列的同时进行的,以下方法为将消息加入队列并指定队列的处理模式、联合模式的方法:
方法一:
enqueueNotification:postingStyle:
方法二:
enqueueNotification:postingStyle:coalesceMask:forModes:
四、实际使用方法
1、注册(及注销)监听者
例:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aWindowBecameMain:) name:NSWindowDidBecomeMainNotification object:nil];
需要在监听者dealloc之前到消息中心进行注销:
[[NSNotificationCenter defaultCenter] removeObserver:self];
2、 消息的创建及发送
(1)消息的创建
用NSNotification类的方法创建:
方法一:notificationWithName:object:
方法二:notificationWithName:object:userInfo:
(2)创建消息同时发送消息
利用NSNotificationCenter创建并发送消息(这个方法更常用):
首先通过[NSNotificationCenter defaultCenter];
获取消息中心
然后调用以下方法创建并发送消息:
方法一:postNotificationName:object:
方法二:postNotificationName:object:userInfo:
比如:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ConverterAdded" object:self];
这样发送的消息是不能修改的。
(3)创建消息并加入消息队列
通过NSNotificationQueue的类方法获取消息队列:
方法:+(NSNotificationQueue *)defaultQueue;
将通过(1)创建的消息加入消息队列:
方法一:
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray<NSString *> *)modes;
方法二:
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle;