RN 47 中的 JS 线程及 RunLoop

Posted huahuahu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RN 47 中的 JS 线程及 RunLoop相关的知识,希望对你有一定的参考价值。

RCBridge 初始化时声明了一个 CADisplayLink

_jsDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_jsThreadUpdate:)];

_jsThreadUpdate 函数中,处理界面更新。这个 CADisplayLink 随后被加到 JS 线程对应的 RunLoop 中。

- (void)addToRunLoop:(NSRunLoop *)runLoop
{
  _runLoop = runLoop;
  [_jsDisplayLink addToRunLoop:runLoop forMode:NSRunLoopCommonModes];
}

RCTCxxBridge 声明了一个 thread

  _jsThread = [[NSThread alloc] initWithTarget:self
                                      selector:@selector(runJSRunLoop)
                                        object:nil];
  _jsThread.name = RCTJSThreadName;
  _jsThread.qualityOfService = NSOperationQualityOfServiceUserInteractive;
  [_jsThread start];

并为这个 thread 声明了要给 RunLoop

// copy thread name to pthread name
pthread_setname_np([NSThread currentThread].name.UTF8String);

// Set up a dummy runloop source to avoid spinning
CFRunLoopSourceContext noSpinCtx = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
CFRunLoopSourceRef noSpinSource = CFRunLoopSourceCreate(NULL, 0, &noSpinCtx);
CFRunLoopAddSource(CFRunLoopGetCurrent(), noSpinSource, kCFRunLoopDefaultMode);
CFRelease(noSpinSource);

RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");

// run the run loop
while (kCFRunLoopRunStopped != CFRunLoopRunInMode(kCFRunLoopDefaultMode, ((NSDate *)[NSDate distantFuture]).timeIntervalSinceReferenceDate, NO)) {
  RCTAssert(NO, @"not reached assertion"); // runloop spun. that\'s bad.
}

RunLoop 的调用方式之 performSelector

如下,原因是因为有如下调用:

  if ([NSThread currentThread] == _jsThread) {
    [self _tryAndHandleError:block];
  } else {
    [self performSelector:@selector(_tryAndHandleError:)
          onThread:_jsThread
          withObject:block
          waitUntilDone:NO];
  }

在 RunLoop 上执行一函数

  CFRunLoopPerformBlock(m_cfRunLoop, kCFRunLoopCommonModes, ^{ func(); });

Enqueues a block object on a given runloop to be executed as the runloop cycles in specified modes.

CADisplayLink 加到指定的 RunLoop 中,然后相应

_jsDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_jsThreadUpdate:)];
[_jsDisplayLink addToRunLoop:runLoop forMode:NSRunLoopCommonModes];

以上是关于RN 47 中的 JS 线程及 RunLoop的主要内容,如果未能解决你的问题,请参考以下文章

iOS中的RunLoop

深入研究 Runloop 与线程保活

Runloop

多线程RunLoop

你了解 RunLoop 线程保活吗?已封装好,2 句代码直接使用

RunLoop基础