如题,今天的博客咱们就来记录一下iOS开发中使用MachPort来实现线程间的通讯,而后使用该知识点来转发子线程中所发出的Notification。简单的说,MachPort的工做方式实际上是将NSMachPort的对象添加到一个线程所对应的RunLoop中,并给NSMachPort对象设置相应的代理。在其余线程中调用该MachPort对象发消息时会在MachPort所关联的线程中执行相关的代理方法。html
下方内容咱们先来看一下MachPort的工做方式,而后再看一下在子线程中发Notification的效果,最后咱们在经过MachPort来说子线程中的发出的通知转发到主线程中进行处理。git
1、MachPort的使用方式github
接下来咱们就经过一个小的示例来简单的看一下MachPort的使用方式。首先咱们声明了一个NSMachPort的成员属性handelEventMachPort,该变量实例化后指定其NSMachPortDelegate的对象为当前类。而后将handelEventMachPort添加到主线程中,具体代码以下所示。app
搞定NSMachPort对象后,接下来咱们要在当前VC实现NSMachPortDelegate代理中相关的方法,以下所示。当在其余线程中调用上述的MachPort对象发送消息时,会在主线程中执行下方的代理方法。在该方法中咱们打印了该方法执行时所在的线程,具体代码以下所示:异步
实例化完MachPort对象以及实现其相关的代理方法后,接下来要作的事情就是开辟一个新的线程,而后在这个新的线程中调用handelEventMachPort对象,往主线程所对应的RunLoop中发送消息。 oop
代码实现完毕后,接下来就该看一下运行效果了。下方就是上述代码示例所运行的结果。从结果中咱们不难看出,点击按钮时,会开启一个新的子线程,咱们将这个开启的子线程命名为“MySubThread”。在这个子线程中咱们调用了与主线程关联的MachPort对象发送消息。而后在主线程中执行该MachPort对象的相关回调方法,每次点击按钮的输出以下所示:ui
2、子线程中Notification的发送spa
该部分算是为下一部分作铺垫的,本部分的代码示例比较简单。作的事情主要是在主线程中注册一个观察者,而后在开启的子线程中发送通知,咱们来看一下处理该通知的方法所处的线程。线程
下方就是本部分的核心代码,代码比较简单。首先咱们打印出注册观察者的线程,而后往通知中心添加观察者。紧接着咱们就建立一个子线程,而后对子线程的信息进行打印并获取通知中心单例发送通知。3d
而后在收到通知事件所执行的方法中,咱们要作的事情就是对执行该方法的线程进行打印。具体代码以下所示:
实现完上述代码后,下方是上述代码的运行结果。从结果中咱们不难发现,虽然是在主线程中添加的观察者,可是若是在子线程中发出通知,那么就在该子线程中处理通知所关联的方法,具体效果以下所示:
3、将子线程发出的通知经过MachPort转发到主线程中进行处理
接下来所作的事情就是将第一部分和第二部分的内容进行整合。也就是将子线程发出的通知经过MachPort转发到主线程中进行处理。下方的代码示例咱们参考了Apple Developer中的相关示例(连接请戳我)。固然了,对其官方示例咱们作了一些修改,目的是为了更易于理解。
首先仍是得实现NSMachPortDelegate相关协议中的方法,下方代码段中的notificationQueue用来纯粹子线程发出的全部通知,mainThread则是用来储存主线程了,lock则是对通知队列加锁,避免多个线程同时操做该队列所出现的数据不一致问题。mackPort则是用于向指望线程发送信号的通讯端口。
下方的代码段则是对上述字段的赋值。
接着咱们在viewDidLoad方法中打印了注册通知的线程,固然此处是主线程了。而后在子线程中异步的发送一条通知,具体代码以下所示:
下方就是收到通知后所执行的方法,在该方法中,咱们看到作了一个判断。若是该方法是在咱们预期的主线程中被执行的话,那么咱们就执行收到通知后所要执行的任务。若是不是咱们预期的主线程的话,接下来走的就是经过MachPort来转发到主线程了。
在转发通知前要把当前方法所接收到的notification入队列暂存,等转发后,在MachPort的相关代理方法中取出相关的通知并作相关处理。
下方代码段就是处理MachPort所转发过来的消息。在该方法中取出了队列中暂存的相关通知并进行了相关处理。代码以下所示。
下方是具体的运行结果:
本篇博客所涉及demo在github上的分享地址以下: