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:selfselector:@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:_jsThreadwithObject:blockwaitUntilDone: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];