NSDistributedNotificationCenter +defaultCenter 访问,这个distributed notification center 处理 单个机器不一样线程之间的通知。若须要不一样的机器之间通讯,须要使用distrubted object
用NSNotificationQueue
’s enqueueNotification:postingStyle:
and enqueueNotification:postingStyle:coalesceMask:forModes:的方法,你能够把通知放到queue里面异步的发送给线程。吧通知放到queue之后这些方法会马上返回,不作等待。
notification有三种style放到queue, NSPostASAP
, NSPostWhenIdle
, and NSPostNow
.
以NSPostASAP
风格进入队列的通告会在运行循环的当前迭代完成时被发送给通告中心,若是当前运行循环模式和请求的模式相匹配的话(若是请求的模式和当前模式不一样,则通告在进入请求的模式时被发出)。因为运行循环在每一个迭代过程当中可能进行多个调用分支(callout),因此在当前调用分支退出及控制权返回运行循环时,通告可能被分发,也可能不被分发。其它的调用分支可能先发生,好比定时器或由其它源触发了事件,或者其它异步的通告被分发了。html
您一般能够将NSPostASAP
风格用于开销昂贵的资源,好比显示服务器。若是在运行循环的一个调用分支过程当中有不少客户代码在窗口缓冲区中进行描画,在每次描画以后将缓冲区的内容刷新到显示服务器的开销是很昂贵的。在这种状况下,每一个draw...
方法都会将诸如“FlushTheServer” 这样的通告排入队列,并指定按名称和对象进行聚结,以及使用NSPostASAP
风格。结果,在运行循环的最后,那些通告中只有一个被派发,而窗口缓冲区也只被刷新一次。编程
以NSPostWhenIdle
风格进入队列的通告只在运行循环处于等待状态时才被发出。在这种状态下,运行循环的输入通道中没有任何事件,包括定时器和异步事件。以NSPostWhenIdle
风格进入队列的一个典型的例子是当用户键入文本、而程序的其它地方须要显示文本字节长度的时候。在用户输入每个字符后都对文本输入框的尺寸进行更新的开销是很大的(并且不是特别有用),特别是当用户快速输入的时候。在这种状况下,Cocoa会在每一个字符键入以后,将诸如“ChangeTheDisplayedSize”这样的通告进行排队,同时把聚结开关打开,并使用NSPostWhenIdle
风格。当用户中止输入的时候,队列中只有一个“ChangeTheDisplayedSize”通告(因为聚结的缘由)会在运行循环进入等待状态时被发出,显示部分也所以被刷新。请注意,运行循环即将退出(当全部的输入通道都过期的时候,会发生这种状况)时并不处于等待状态,所以也不会发出通告。缓存
以NSPostNow
风格进入队列的通告会在聚结以后,当即发送到通告中心。您能够在不须要异步调用行为的时候 使用NSPostNow
风格(或者经过NSNotificationCenter的postNotification:
方法来发送)。在不少编程环境下,咱们不只容许同步的行为,并且但愿使用这种行为:即您但愿通告中心在通告派发以后返回,以便肯定观察者对象收到通告并进行了处理。固然,当您但愿经过聚结移除队列中相似的通告时,应该用enqueueNotification
...方法,且使用NSPostNow
风格,而不是使用postNotification:
方法。服务器
Notifications网络
Notification包装了事件的信息, 好比窗口正在获取焦点或者网络链接正在断开. 须要订阅事件(例如, 一个文件想要知道正在编辑它的窗口将要被关闭)的object须要在notification center注册, 以后当事件发生的时候就会获得通知. 当事件发生的时候, 一个notification会被发送到notification center, 然后notification center立刻就会把这个notification转发给全部订阅过这个事件的object. 当须要的时候, notification会被缓存在notification queue中….多线程
Notification的原理app
在两个object之间传递信息最标准的方法是传递消息 – 一个object调用另一个object的方法. 可是, 传递的消息这种方法要求发送消息的object知道消息的接收者和它能接收的消息类型. 这将会把两个object紧密的绑定起来 – 最值得注意的是这会让两个原本独立的子系统耦合在一块儿. 为了解决这些问题, 广播模型被提了出来. Object只是负责发送notification, 而NSNotificationCenter将负责把这个notification转发给全部相关的object.异步
一个NSNotification(在这片文章里面简称notification)包含一个name, 一个object和一个可选的dictionary. Name是notification的标识. Object包含notification发送者想要发送的任意类型的object(通常来讲就是发送这个notification的object自己). Dictionary用来保存其余相关的东西(若是有的话).oop
任意object均可以发送notification. 任意object均可以在notification center注册以便在某个事件发生的时候可以获得通知. Notification center负责把接受的notification发送给全部注册过的消息接收者. 发送notification的object, notification里面包含的object和接收这个notification的object能够是同一个object, 也能够是三个不一样的object. 发送notification的object不须要知道关于接受者的任何信息. 可是, 接受者至少须要知道notification的name和其所包含dictionary的key(若是有的话).post
Notification和Delegation
就使用上看, notification系统和delegate很像, 可是他们有如下不一样:
*Notification的接受者能够是多个object. 可是delegate object只能有一个. 这就阻止了返回值.
*一个object能够从notification center接受它想要的任意数量个notification, 而delegate只能接受预先定义好的delegate方法.
*发送notification的object彻底不知到接受者是否存在.
Notification Centers
Notification center负责接收和发送notification. 当它接受到notification的时候会通知全部符合特定条件的接受者. Notification信息被包装在NSNotification里. Notification接收者在notification center里面注册以得到其余object发出的notification. 当事件发生的时候, 一个object发送相关的notification到notification center. Notification center将消息分发给每个注册过的接受者. 发送notification的object和接受者多是同一个.
Cocoa包含两种notification center:
*NSNotificationCenter类管理单个进程内部的notification.
*NSDistributedNotificationCenter管理一台机器上跨进程的notification.
NSNotificationCenter
每个进程都有一个默认的notification center, 你能够经过访问 NSNotificationCenter 的 +defaultCenter方法来获得它. 这种类型的notification center负责管理单个进程内部的notification. 若是须要管理同一台机器上不一样进程之间的notification则须要用到NSDistributedNotificationCenter.
Notification center发送notification给接收者的方法是同步的. 也就是说, 当发送一个notification的时候, 除非全部的接收者都接到和处理了这个notification, 不然不会返回. 想要发送异步notification的话就须要用到notification queue了.
在一个多线程应用程序里, notification老是和发送者处于同一个线程里, 可是接受者能够在其余线程里.
NSDistributedNotificationCenter
每个进程都有一个默认的distributed notification center, 你能够经过访问 NSDistributedNotificationCenter 的 +defaultCenter方法来获得它. 这种类型的notification center负责管理一台机器上多个进程之间的notification. 若是须要在多台机器间通信的话, 使用distributed objects.
发送一个distributed notification是很是昂贵的. Notification首先会被发送到一个系统级别的服务器上, 而后在分别分发到每个注册过的进程里. 从发从消息到消息被接受到之间的延迟理论上来讲是无限的. 事实上, 若是太多的notification被发送到服务器上, 那么服务器上的notification队列可能会被撑满, 这就有可能会形成notification的丢失.
Distributed notification会在一个进程的主循环里被发送出去. 一个进程必须保证有一个主循环在其内部运行, 例如 NSDefaultRunLoopMode, 而后才能接受到distributed notification. 若是接收进程是多线程的, 那么notification并不必定会被主线程接受到. 通常来讲notification会被分发到主线程的主循环, 可是其余线程同样能够接收到.
通常类型的notification center能够注册全部object的notification, 可是 distributed notification center只能注册字符串类型的notification. 由于发送者和接受者可能在不一样进程里, notification里面包含的object不能保证指向同一个object. 因此, distributed notification center只能接受包含字符串类型的notification. Notification会基于字符串来匹配.