初始化主线程port:
// 在主线程中初始化
_mainPort = [NSMachPort port]
[NSRunLoop.currentRunLoop addPort:_mainPort forMode:NSDefaultRunLoopMode]
初始化子线程port:
// 在子线程中初始化
_otherPort = [NSMachPort port]
_otherPort.delegate = self
[NSRunLoop.currentRunLoop addPort:_otherPort forMode:NSDefaultRunLoopMode]
// 创建runloop观察者
CFRunLoopObserverRef obs = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, true, 0, observerCallBack, NULL)
CFRunLoopAddObserver([NSRunLoop.currentRunLoop getCFRunLoop], obs, kCFRunLoopDefaultMode)
CFRelease(obs)
// 子线程的runloop需要主动启动
[NSRunLoop.currentRunLoop run]
实现代理方法:
#pragma mark - NSMachPortDelegate
- (void)handleMachMessage:(void *)msg {
NSLog(@"%s", __func__);
}
控制台打印:

主线程port给子线程port发送消息:
[_otherPort sendBeforeDate:NSDate.distantFuture components:nil from:_mainPort reserved:0];
控制台打印:

总结:
- 从打印信息可以看到source1是在kCFRunLoopAfterWaiting之后执行的,说明source1有消息到来时会自动唤醒runloop,处理完之后再次进入休眠kCFRunLoopBeforeWaiting,直到下一次消息到来被再次唤醒
- 跟source0一样,处理完消息之后同样会退出(kCFRunLoopExit)再进入(kCFRunLoopEntry)