⚠️ For Your Infomation:笔者非专业客户端开发人员,以下分析过程并不保证完全正确,并且加载过程是点到为止,不涉及 JS 解析与 OC 底层部分,请酌情阅读 以下代码基于 React Native 0.70.0 版本分析
在阅读本文前,您有必要需要了解 RCTBridge
。根据其头文件的注释,它是这么被定义的:
/**
* Async batched bridge used to communicate with the JavaScript application.
*/
@interface RCTBridge : NSObject <RCTInvalidating>
也就是说 RCTBridge
是个用来与 JS 批量且异步通讯的桥,其作用类似于微信小程序用于 Webview 与 Native 通讯的 JSBridge。
在前一篇文章中,您已经了解到 JSBundle 具体位置,为了溯源 JSBundle 的加载,就需要了解谁调用了 sourceURLForBridge
。通过搜索源码,可找到是在 RCTBridge 初始化的时候调用的。
// React/Base/RCTBridge.m
- (void)setUp
{
// ...
Class bridgeClass = self.bridgeClass;
// Only update bundleURL from delegate if delegate bundleURL has changed
NSURL *previousDelegateURL = _delegateBundleURL;
_delegateBundleURL = [self.delegate **sourceURLForBridge:self**];
if (_delegateBundleURL && ![_delegateBundleURL isEqual:previousDelegateURL]) {
_bundleURL = _delegateBundleURL;
}
// 获取 bundle 绝对路径
_bundleURL = [RCTConvert NSURL:_bundleURL.absoluteString];
// bridgeClass = RCTCxxBridge
self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
[self.batchedBridge start];
}
在得到 Bundle 地址后,会初始化 RCTCxxBridge(bridgeClass)
,并赋值给 batchedBridge
属性,然后执行 batchedBridge
的 start
方法,也就是 RCTCxxBridge.start()
RCTCxxBridge.initWithParentBridge
不作过多解释,这里的核心工作是将挂载 RCTBridge
到 RCTCxxBridge
上,还有一些非必要的事件与日志注册
bridgeClass
可理解为是一种依赖倒置,这里传入的是RCTCxxBridge
的实现(早期版本是RCTBatchedBridge
)
start
函数主要工作如下:
RCTJavaScriptWillStartLoadingNotification
事件,即 JS 线程启动前事件RCTModuleRegistry
注册 Native Modulesreact.Instance
(使用 C++ 实现)对象,并挂载到 this
TurboModuleRegistry
,即 TurboModule 的注册入口(这里先跳过)