iOS RunLoop处理source1详解

102 阅读1分钟
初始化主线程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__);
}
控制台打印:

11.png

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

22.png

总结:

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