iOS开发之线程间的MachPort通信与子线程中的Notification转发

2018 年 1 月 5 日 CocoaChina 青玉伏案

如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification。简单的说,MachPort的工作方式其实是将NSMachPort的对象添加到一个线程所对应的RunLoop中,并给NSMachPort对象设置相应的代理。在其他线程中调用该MachPort对象发消息时会在MachPort所关联的线程中执行相关的代理方法。


下方内容我们先来看一下MachPort的工作方式,然后再看一下在子线程中发Notification的效果,最后我们在通过MachPort来讲子线程中的发出的通知转发到主线程中进行处理。


一、MachPort的使用方式


接下来我们就通过一个小的示例来简单的看一下MachPort的使用方式。首先我们声明了一个NSMachPort的成员属性handelEventMachPort,该变量实例化后指定其NSMachPortDelegate的对象为当前类。然后将handelEventMachPort添加到主线程中,具体代码如下所示。

  


搞定NSMachPort对象后,接下来我们要在当前VC实现NSMachPortDelegate代理中相关的方法,如下所示。当在其他线程中调用上述的MachPort对象发送消息时,会在主线程中执行下方的代理方法。在该方法中我们打印了该方法执行时所在的线程,具体代码如下所示:



实例化完MachPort对象以及实现其相关的代理方法后,接下来要做的事情就是开辟一个新的线程,然后在这个新的线程中调用handelEventMachPort对象,往主线程所对应的RunLoop中发送消息。 



代码实现完毕后,接下来就该看一下运行效果了。下方就是上述代码示例所运行的结果。从结果中我们不难看出,点击按钮时,会开启一个新的子线程,我们将这个开启的子线程命名为“MySubThread”。在这个子线程中我们调用了与主线程关联的MachPort对象发送消息。然后在主线程中执行该MachPort对象的相关回调方法,每次点击按钮的输出如下所示:



二、子线程中Notification的发送


该部分算是为下一部分做铺垫的,本部分的代码示例比较简单。做的事情主要是在主线程中注册一个观察者,然后在开启的子线程中发送通知,我们来看一下处理该通知的方法所处的线程。


下方就是本部分的核心代码,代码比较简单。首先我们打印出注册观察者的线程,然后往通知中心添加观察者。紧接着我们就创建一个子线程,然后对子线程的信息进行打印并获取通知中心单例发送通知。


然后在收到通知事件所执行的方法中,我们要做的事情就是对执行该方法的线程进行打印。具体代码如下所示:



实现完上述代码后,下方是上述代码的运行结果。从结果中我们不难发现,虽然是在主线程中添加的观察者,但是如果在子线程中发出通知,那么就在该子线程中处理通知所关联的方法,具体效果如下所示:



三、将子线程发出的通知通过MachPort转发到主线程中进行处理


接下来所做的事情就是将第一部分和第二部分的内容进行整合。也就是将子线程发出的通知通过MachPort转发到主线程中进行处理。下方的代码示例我们参考了Apple Developer中的相关示例(链接请戳我)。当然了,对其官方示例我们做了一些修改,目的是为了更易于理解。


首先还是得实现NSMachPortDelegate相关协议中的方法,下方代码段中的notificationQueue用来纯粹子线程发出的所有通知,mainThread则是用来储存主线程了,lock则是对通知队列加锁,避免多个线程同时操作该队列所出现的数据不一致问题。mackPort则是用于向期望线程发送信号的通信端口。



下方的代码段则是对上述字段的赋值。



接着我们在viewDidLoad方法中打印了注册通知的线程,当然此处是主线程了。然后在子线程中异步的发送一条通知,具体代码如下所示:



 下方就是收到通知后所执行的方法,在该方法中,我们看到做了一个判断。如果该方法是在我们预期的主线程中被执行的话,那么我们就执行收到通知后所要执行的任务。如果不是我们预期的主线程的话,接下来走的就是通过MachPort来转发到主线程了。


在转发通知前要把当前方法所接收到的notification入队列暂存,等转发后,在MachPort的相关代理方法中取出相关的通知并做相关处理。 



下方代码段就是处理MachPort所转发过来的消息。在该方法中取出了队列中暂存的相关通知并进行了相关处理。代码如下所示。



下方是具体的运行结果:



本篇博客所涉及demo在github上的分享地址如下:


https://github.com/lizelu/NotificationWithSubThread


登录查看更多
0

相关内容

iOS 是苹果公司为其移动产品开发的操作系统。它主要给 iPhone、iPod touch、iPad 以及 Apple TV 使用。原本这个系统名为 iPhone OS,直到2010年6月7日 WWDC 大会上宣布改名为 iOS。
【2020新书】实战R语言4,323页pdf
专知会员服务
101+阅读 · 2020年7月1日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
58+阅读 · 2020年6月26日
【Manning新书】现代Java实战,592页pdf
专知会员服务
100+阅读 · 2020年5月22日
专知会员服务
32+阅读 · 2020年5月20日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
118+阅读 · 2020年5月10日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
88+阅读 · 2019年11月25日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
23+阅读 · 2019年11月7日
Kali Linux 渗透测试:密码攻击
计算机与网络安全
16+阅读 · 2019年5月13日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
逆向 | C++ 加壳程序的编写思路
计算机与网络安全
9+阅读 · 2019年1月1日
在浏览器中使用tensorflow.js进行人脸识别的JavaScript API
人工智能头条
6+阅读 · 2018年7月2日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
大数据分析研究组开源Easy Machine Learning系统
中国科学院网络数据重点实验室
16+阅读 · 2017年6月13日
Area Attention
Arxiv
5+阅读 · 2019年5月23日
dynnode2vec: Scalable Dynamic Network Embedding
Arxiv
14+阅读 · 2018年12月6日
Mobile big data analysis with machine learning
Arxiv
6+阅读 · 2018年8月2日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
101+阅读 · 2020年7月1日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
58+阅读 · 2020年6月26日
【Manning新书】现代Java实战,592页pdf
专知会员服务
100+阅读 · 2020年5月22日
专知会员服务
32+阅读 · 2020年5月20日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
118+阅读 · 2020年5月10日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
88+阅读 · 2019年11月25日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
23+阅读 · 2019年11月7日
相关资讯
Kali Linux 渗透测试:密码攻击
计算机与网络安全
16+阅读 · 2019年5月13日
PHP使用Redis实现订阅发布与批量发送短信
安全优佳
7+阅读 · 2019年5月5日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
逆向 | C++ 加壳程序的编写思路
计算机与网络安全
9+阅读 · 2019年1月1日
在浏览器中使用tensorflow.js进行人脸识别的JavaScript API
人工智能头条
6+阅读 · 2018年7月2日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
大数据分析研究组开源Easy Machine Learning系统
中国科学院网络数据重点实验室
16+阅读 · 2017年6月13日
Top
微信扫码咨询专知VIP会员