如题,今天的博客我们就来记录一下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

iOS开发之线程间的MachPort通信与子线程中的Notification转发的更多相关文章

  1. iOS开发之使用XMPPFramework实现即时通信(三)

    你看今天是(三)对吧,前面肯定有(一)和(二),在发表完iOS开发之使用XMPPFramework实现即时通信(一)和iOS开发之使用XMPPFramework实现即时通信(二)后有好多的小伙伴加我Q ...

  2. iOS开发之使用XMPPFramework实现即时通信(二)

    上篇的博客iOS开发之使用XMPPFramework实现即时通信(一)只是本篇的引子,本篇博客就给之前的微信加上即时通讯的功能,主要是对XMPPFramework的使用.本篇博客中用到了Spark做测 ...

  3. iOS开发之使用XMPPFramework实现即时通信

    iOS开发之使用XMPPFramework实现即时通信   关于XMPP的理论介绍在本篇博客中就不做赘述了,如何在我们之前的微信中加入XMPP协议来实现通信呢?下面将会介绍一下XMPP的基本的知识,让 ...

  4. 线程间使用socket通信的计算器

    该程序是处理平时的算数运算,程序也没有什么特别之处,只是将所有运算分开运算,每个函数(线程)处理不同的运算符号里面的运算,然后将所有结果都汇总到main函数中进行最后汇总(相加减)运算,每个函数内都处 ...

  5. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

  6. JUC之线程间定制化通信

    线程通信之定制化 之前文章中写了下Condition的使用,这里我们详细说下其中的用法: 首先使用Condition需要实例化Lock private Lock lock = new Reentran ...

  7. rtt学习之线程间同步与通信

    一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...

  8. ios开发总结,日常开发:ios开发功能收集,经验分享等等(不断更新中。。。)

    github资料学习和下载地址:https://github.com/niexiaobo/MyDailyDevelopmentNotes ios 学习模块 ios APP 日志管理的重要性: 一个功能 ...

  9. 线程:Java主线程等待子线程结束

    使用Thread.join()方法: public class App { public static void main(String[] args) { testMain(); } public ...

随机推荐

  1. Very Simple Problem

    Very Simple Problem Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  2. shell命令输入输出重定向

    Linux命令的执行过程 首先是输入:stdin输入可以从键盘,也可以从文件得到 命令执行完成:把成功结果输出到屏幕,stout默认是屏幕 命令执行有错误:把错误也输出到屏幕上面,stderr默认也是 ...

  3. [转]彻底弄懂css中单位px和em,rem的区别

    难怪会问我 rem 和 em, 这俩或在移动端还是很有必要学习的. root em OK? 国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem,那么三者有什么区别,又各自有什么优劣呢? P ...

  4. mysql +keeplive

    下载tar包 ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-431.el6. ...

  5. Linux学习决心书

    学习Linux决心计划书 我叫耿长学,来自河南省邓州市,经过老男孩教育运维班5个月学习后,我一定要达到的薪水目标是11000元,为了达到此目标我将采取如下10大行动或方案: 1.每天早上5:30-6: ...

  6. eclipse中导入jsp等工程使用过程中常遇问题

    1.导入的工程JSP文件出现报错的情况 这个一般不怎么影响文件的执行,这些文件飘红主要是因为eclipse的校验问题. 具体错误信息:Multiple annotations found at thi ...

  7. C# 读写文本文件乱码解决方案

    在使用C#对文本文件读取的时候,如果其中包含了中文,经常会出现乱码.一般解决是在StreamReader加一个编码,我使用的是Encoding.UTF8,一般情况下使用这个参数就可以.但是,在这次我使 ...

  8. 学会WCF之试错法——安全配置报错分析

    安全配置报错分析 服务端配置 <system.serviceModel> <bindings> <wsHttpBinding> <binding name = ...

  9. linux操作系统基础篇(一)

    1.什么是linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序 ...

  10. .net SignalR winform 推送广播

    最近在做一个项目,需要用到服务端主动推送给客户端,最开始用的是自己比较顺手的Remoting,可后来发现把服务端架到外网上,就猴子它哥了,后来又尝试WCF,虽然能推送,但是推了几次也猴子它哥了,后来找 ...