如题,今天的博客我们就来记录一下 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
来源: http://www.cnblogs.com/ludashi/p/7460907.html