NSNotificationCenter
这是个单例类,负责管理通知的创建和发送,属于最核心的类了。而NSNotificationCenter
类主要负责三件事
- 添加通知
- 发送通知
- 移除通知
NSNotificationQueue
功能介绍
通知队列,用于异步发送消息,这个异步并不是开启线程,而是把通知存到双向链表实现的队列里面,等待某个时机触发时调用NSNotificationCenter
的发送接口进行发送通知,这么看NSNotificationQueue
最终还是调用NSNotificationCenter
进行消息的分发
另外NSNotificationQueue
是依赖runloop
的,所以如果线程的runloop
未开启则无效,至于为什么依赖runloop
下面会解释
NSNotificationQueue
主要做了两件事:
- 添加通知到队列
- 删除通知
NSNotificationCenter
是同步发送的,而这里介绍关于NSNotificationQueue
的异步发送,从线程的角度看并不是真正的异步发送,或可称为延时发送,它是利用了runloop
的时机来触发的
对于NSNotificationQueue
总结如下
- 依赖
runloop
,所以如果在其他子线程使用NSNotificationQueue
,需要开启runloop - 最终还是通过
NSNotificationCenter
进行发送通知,所以这个角度讲它还是同步的 - 所谓异步,指的是非实时发送而是在合适的时机发送,并没有开启异步线程
主线程响应通知
异步线程发送通知则响应函数也是在异步线程,如果执行UI刷新相关的话就会出问题,那么如何保证在主线程响应通知呢?
其实也是比较常见的问题了,基本上解决方式如下几种:
- 使用
addObserverForName: object: queue: usingBlock
方法注册通知,指定在mainqueue
上响应block
- 在主线程注册一个
machPort
,它是用来做线程通信的,当在异步线程收到通知,然后给machPort
发送消息,这样肯定是在主线程处理的
RunLoop是一个接收处理异步消息事件的循环,一个循环中:等待事件发生,然后将这个事件送到能处理它的地方。
runLoop实际上是一个对象,这个对象在循环中用来处理程序运行过程中出现的各种事件(比如说触摸事件、UI刷新事件、定时器事件、Selector事件)和消息,从而保持程序的持续运行;而且在没有事件处理的时候,会进入睡眠模式,从而节省CPU资源,提高程序性能。