IOS消息分发(广播)机制

2024-09-06 00:48
文章标签 广播 ios 消息 机制 分发

本文主要是介绍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参数传递出去。

[objc]  view plain copy
  1. -(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation  
  2. {  
  3.     NSNotificationCenter* notify = [NSNotificationCenter defaultCenter]; // 获取Notification center对象,默认每个APP均有一个单例defaultCenter  
  4.       
  5.     [notify postNotificationName:@"OpenPDF" object:url];  
  6.     return YES;  
  7. }  


上面的处理中,有这么几点:

1、首先获得NSNotificationCenter对象,这里我们通过类方法获取了一个defaultCenter对象。在IOS中,每个App中都会有一个系统默认的defaultCenter对象。

2、我们向Notification center发送消息,调用了postNotificationName:object:方法。其实在该方法中,我们同时创建了一个Notification对象,该方法会将该消息对象发送到notification center中。(其实我们也可以先创建一个Notification对象,再通过调用方法发送该对象,但是现在使用的方法更简洁)

在IOS中,消息也是一个对象的形式存在的,其有三个属性如下:

[objc]  view plain copy
  1. @interface NSNotification : NSObject <NSCopying, NSCoding>  
  2.   
  3. @property (readonlycopyNSString *name;        // 消息名称  
  4. @property (readonlyretainid object;           // 消息附加的对象信息  
  5. @property (readonlycopyNSDictionary *userInfo;// 消息附加的用户自定义扩展信息  

上面三个属性的具体内容都是由sender定义的,其中name可以让我们区别是什么消息,而object和userInfor则可以附带一些消息发出时的附加信息供消息接受者处理。(object属性通常会设置为消息发出者自身self,这样observer就可以通过订阅时指定name 和 object属性来确定感兴趣的消息,并指定其来自那个object)。

3、observer注册感兴趣的消息到notification center,并指明处理消息的selector或块。

这里,在ViewController的viewDidLoad中,我注册了感兴趣的通知,OpenPDF。并指明处理的selector为openPDFAction:

[objc]  view plain copy
  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.     // Do any additional setup after loading the view, typically from a nib.  
  4.     NSNotificationCenter* notify = [NSNotificationCenter defaultCenter];  
  5.     [notify addObserver:self selector:@selector(openPDFAction:) name:@"OpenPDF" object:nil];   
  6. }  

在订阅消息函数中,我们并没有指定要订阅那个object,所以不管是那个sender的消息,只要名字等于OpenPDF,则Notification center就会通知我们,并调用我们的处理函数openPDFAction。

4、处理函数的定义一般如下,其参数仅有一个,就是被转发过来的Notification对象,同时,没有返回值(因为一个消息可能会被转发至多个Observer,对于返回值来说就没有必要了,否则,你应使用那个处理函数的返回值呢?)

[objc]  view plain copy
  1. -(void) openPDFAction:(NSNotification*) sender  
  2. {  
  3.     NSURL* URL = (NSURL*)[sender object];  
  4.     if (URL) {  
  5.         self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:URL];  
  6.         [self.documentInteractionController setDelegate:self];  
  7.         [self.documentInteractionController presentPreviewAnimated:YES];  
  8.     }  
  9.   
  10. }  

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消息分发(广播)机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140524

相关文章

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

SpringIntegration消息路由之Router的条件路由与过滤功能

《SpringIntegration消息路由之Router的条件路由与过滤功能》本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理... 目录引言一、Router基础概念二、条件路由实现三、基于消息头的路由四、动态路由与路由表五、消息过滤

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst

springboot rocketmq配置生产者和消息者的步骤

《springbootrocketmq配置生产者和消息者的步骤》本文介绍了如何在SpringBoot中集成RocketMQ,包括添加依赖、配置application.yml、创建生产者和消费者,并展... 目录1. 添加依赖2. 配置application.yml3. 创建生产者4. 创建消费者5. 使用在

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

一文详解Java Condition的await和signal等待通知机制

《一文详解JavaCondition的await和signal等待通知机制》这篇文章主要为大家详细介绍了JavaCondition的await和signal等待通知机制的相关知识,文中的示例代码讲... 目录1. Condition的核心方法2. 使用场景与优势3. 使用流程与规范基本模板生产者-消费者示例