1.OC在 RCTRootView 建立 Bridge
2.使用 setUp 初始化
主要调用 setUp 创建 BatchedBridge(用于批量读取js对OC的方法调用,同时其内部有一个JavaScriptExecutor 执行js代码)
3.创建 BatchedBridge 的关键是 start 方法
- 读取js源码
- 初始化模块信息
- 初始化js代码执行器 即 RCTJSCExecutor
- 生成模块列表并写入js端
- 执行js源码
初始化模块信息
initModulesWithDispatchGroup中实现
RCT_EXPORT_MODULE 重写了 load 方法
load方法中用一个全局数组记录所有需要导出到js的类信息RCT_EXPORT_METHOD 导出oc方法到js 它为函数名添加 rct_export 前缀,再在runtime获取类的函数列表 因此,OC的Bridge就是拥有一个数组,数组中保存了,所有导出给js的类信息 只有给出 ModuleId 和 MethodId 就可以唯一确定要调用的方法。
初始化js代码执行器 即 RCTJSCExecutor 对象 生成模块列表并写入 JavaScript 端
这一步的操作就是为了让 JavaScript 获取所有模块的名字:
- (NSString *)moduleConfig{ NSMutableArray*config = [NSMutableArray new];
for (RCTModuleData *moduleData in _moduleDataByID) {
[config addObject:@[moduleData.name]];
}
}
执行 JavaScript 源码
OC调用 JavaScript 代码
调用 javaScript 的代码
- (void)_executeJSCall:(NSString *)method arguments:(NSArray *)arguments callback:(RCTJavaScriptCallback)onComplete{
[self executeBlockOnJavaScriptQueue:^{
// 获取 contextJSRef、methodJSRef、moduleJSRef
resultJSRef = JSObjectCallAsFunction(contextJSRef,
(JSObjectRef)methodJSRef,
(JSObjectRef)moduleJSRef,
arguments.count,
jsArgs,
&errorJSRef);
objcValue =
/*resultJSRef 转换成 Objective-C 类型*/
onComplete(objcValue, nil); }];
}
在实际使用的时候,我们可以这样发起对 JavaScript 的调用:但 JavaScript 必须设置监听
[_bridge.eventDispatcher sendAppEventWithName:@"greeted" body:@{ @"name": @"nmae"}];
JavaScript 调用 Objective-C
通过编写原生组件,导出函数或者 UI 组件,来调用原生方法
if(Platform.OS === 'ios') {
QRCode = NativeModules.MTQRCodeVC;
} else {
QRCode = NativeModules.QrcodeModule;
}
QRCode.scanWithColor(processColor('rgb(0,255,0)'),(codestring) => {})