本文主要是介绍IOS消息分发(广播)机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在IOS中,提供了通知机制(Notification),可以在对象间传递和接受信息。传递和接受信息的对象间甚至不需要知道对方的存在。究其本质来说,其实是设计模式中的观察者模式的应用。
通知机制
设想这么一个场景:我开发了一款pdf阅读器,当手机上的另一个App打开pdf文件时,通过Open in,选择我的pdf阅读器打开。这时候我的pdf阅读器会被lanuch,同时在其App delegate中application:openURL方法会被调用,在这里我可以获得要打开的pdf文件的URL。然后,我想在App的ViewController中通过调用其他方法来渲染显示pdf文件。那么问题来了,默认的App delegate是和程序的ViewController层面没有联系的,即它不知道ViewController Object的存在,那么我怎么通知ViewController来渲染打开pdf文件并将文件的URL传递过去呢?
可能有人想到通过在App delegate中定义属性记录URL,再在ViewController中通过sharedApplication方式获取。但这种方式我们应该何时调用渲染函数来打开pdf文件呢?
一种更好的方式,就是使用IOS中的Notification机制。
Notification机制允许我们在同一个设备上的单个App中,或多个App间传递消息,甚至在不同设备间传递消息。
Notification由三部分组成:发送消息者、消息中心(负责接送及转发消息)、消息订阅者三个部分。他们的关系如下图所示:
如图所示,Notification机制的流程为:
1、消息发出者(sender)与消息接受者(observer)通过Notification Center建立关系,sender和observer之间互相不知道对方的存在。
2、observer向Notification center注册感兴趣的消息(同一个消息可以被多次注册,这样observer会多次得到相同的消息通知)。
3、sender向Notification center发送消息。
4、Notification center接收到来自sender消息,自动根据注册信息向感兴趣的Observer转发消息。
5、Observer获得来自Notification center的消息处理。
Notification 实例
消息机制能够在同一App的各对象间、不同App间传递消息,这里,就先结合在单个App中的各对象间传递消息为例,来说明如何在代码中使用消息的。
还是以pdf阅读器为例,在App delegate的Open URL方法中,我们获知App因为打开文件而被打开,同时可以获取文件URL地址。这里我们发出一个名称OpenPDF的消息,同时将文件的URL地址作为object参数传递出去。
1、首先获得NSNotificationCenter对象,这里我们通过类方法获取了一个defaultCenter对象。在IOS中,每个App中都会有一个系统默认的defaultCenter对象。
2、我们向Notification center发送消息,调用了postNotificationName:object:方法。其实在该方法中,我们同时创建了一个Notification对象,该方法会将该消息对象发送到notification center中。(其实我们也可以先创建一个Notification对象,再通过调用方法发送该对象,但是现在使用的方法更简洁)
在IOS中,消息也是一个对象的形式存在的,其有三个属性如下:
上面三个属性的具体内容都是由sender定义的,其中name可以让我们区别是什么消息,而object和userInfor则可以附带一些消息发出时的附加信息供消息接受者处理。(object属性通常会设置为消息发出者自身self,这样observer就可以通过订阅时指定name 和 object属性来确定感兴趣的消息,并指定其来自那个object)。
3、observer注册感兴趣的消息到notification center,并指明处理消息的selector或块。
这里,在ViewController的viewDidLoad中,我注册了感兴趣的通知,OpenPDF。并指明处理的selector为openPDFAction:
在订阅消息函数中,我们并没有指定要订阅那个object,所以不管是那个sender的消息,只要名字等于OpenPDF,则Notification center就会通知我们,并调用我们的处理函数openPDFAction。
4、处理函数的定义一般如下,其参数仅有一个,就是被转发过来的Notification对象,同时,没有返回值(因为一个消息可能会被转发至多个Observer,对于返回值来说就没有必要了,否则,你应使用那个处理函数的返回值呢?)
OK,这样我们就完成了一个消息的处理流程了:sender发出消息到Notification center,Observer 注册感兴趣的消息到Notification center,Notification center在有消息时,会自动将消息发送给感兴趣的Observer。在这个流程中,sender和Observer始终不知道对方的存在,他们是通过Notification center建立联系的。
Notification机制的一些细节
1、在单个App中,我们通过NSNotificationCenter对象接收分发消息。若要再多个App间传递消息,则需要NSDistributedNotificationCenter对象。
2、利用NSNotificationCenter对象分发notification是同步的,即直到所有的Observer均接收到消息并处理完成后,调用消息分发的函数才会返回。若想异步处理消息分发,可以借助Notification Queues(一个为NSNotificationCenter对像配备的消息缓存)。
3、消息分发一般来说是不会跨线程的。对于NSNotificationCenter,消息只会在发出消息的线程中传递。对于NSDistributedNotificationCenter,消息只会传递到另一个App的主线程上。
若要实现消息的跨线程分发,一种方法是可以实现自定义的消息缓冲(不是系统的NSNotificationQueue对象),让其在正确的线程上接受消息,然后再像目标线程转发消息。
4、跨App的消息通过系统的转发中心转发,它会消耗大量系统资源,同时不能够保证消息的实时性。若系统中又过多的消息需要传递,IOS系统其实会丢弃一些跨App消息。同时,通过NSDistributedNotificationCenter传递的消息,其object参数仅能是NSString对象,在用户的自定义字典参数中,仅能够存储property list类型。
这篇关于IOS消息分发(广播)机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!