前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RN中native模块是如何暴露给JS的?

RN中native模块是如何暴露给JS的?

原创
作者头像
VV木公子
修改于 2020-04-13 03:24:18
修改于 2020-04-13 03:24:18
10.1K0
举报
文章被收录于专栏:TechBoxTechBox

我们知道,RN可以调用Native侧的方法。并且RN框架也给我们提供了这一能力,只要我们按照某些约定在native侧实现一个方法,那么就可以在JS侧顺利调用。如下实现了一个简单的native模块:

代码语言:txt
AI代码解释
复制
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

@interface NativeLogModule : NSObject<RCTBridgeModule>

@end

#import "NativeLogBridge.h"

@implementation NativeLogModule
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(nativeLog:(id)obj) {
  NSLog(@"开始输出日志:");
  NSLog(@"%@",obj);
  NSLog(@"日志输出完毕!");
}
@end

以上是一段OC写的native代码,NativeLogModule遵守了RN提供的协议RCTBridgeModule。NativeLogModule使用RCT_EXPORT_MODULE()宏将该类以module的方式暴露给JS,然后使用RCT_EXPORT_METHOD将native方法暴露给JS。接下来看下JS侧是怎么调用NativeLogModule的nativeLog方法。

代码语言:txt
AI代码解释
复制
import { NativeModules } from 'react-native';

NativeModules.NativeLogModule.nativeLog('记录点什么吧');

以上两行JS即可实现native方法的调用,第一行是导入NativeModules模块,第二行通过NativeModule调用NativeLogModule

的nativeLog方法。以上即可实现JS调用Native方法。但在学习RN之初,想必大家都有一个疑问,Native方法是怎么暴露给JS的呢?JS又是怎么调用这些Native方法的呢?

这里就不得不说RN中的两个宏了,RCT_EXPORT_MODULE 和 RCT_EXPORT_METHOD。

RCT_EXPORT_MODULE(Native模块暴露给JS)

代码语言:txt
AI代码解释
复制
#define RCT_EXPORT_MODULE(js_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+ (NSString *)moduleName { return @#js_name; } \
+ (void)load { RCTRegisterModule(self); }

如上代码所示,RCT_EXPORT_MODULE宏背后是两个静态方法+(NSString *)moduleName和+(NSString *)load。moduleName方法简单的返回了native模块的类名,如果RCT_EXPORT_MODULE宏的参数是空,就默认导出类名作为模块名,如果参数不是空,就以参数名为模块名。load方法是大家耳熟能详的的,load方法调用RCTRegisterModule函数注册了模块。

让我们再来看看RCTRegisterModule函数的实现(该函数定义在RCTBridge.m中):

代码语言:txt
AI代码解释
复制
static NSMutableArray<Class> *RCTModuleClasses;

void RCTRegisterModule(Class moduleClass)
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    RCTModuleClasses = [NSMutableArray new];
    RCTModuleClassesSyncQueue = dispatch_queue_create("com.facebook.react.ModuleClassesSyncQueue", DISPATCH_QUEUE_CONCURRENT);
  });

  RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
            @"%@ does not conform to the RCTBridgeModule protocol",
            moduleClass);

  // Register module
  dispatch_barrier_async(RCTModuleClassesSyncQueue, ^{
    [RCTModuleClasses addObject:moduleClass];
  });
}

很简单,RCTRegisterModule函数只做了3件事:

1.创建一个全局的可变数组和一个队列(如果数组还不存在)

2.检查导出给JS模块是否遵守了RCTBridgeModule协议

3.把要导出的类添加到全局的可变数组中进行记录

可见,在app启动后调用load方法时,所有需要暴露给JS的方法都已经被注册到一个数组中。到此为止,只是把需要导出给JS的类记录下来了,那这些类又是在什么阶段提供给JS的呢?Native侧全局搜索RCTGetModuleClasses函数,可以看到该函数在RCTCxxBridge的start中被调用了:

代码语言:txt
AI代码解释
复制
- (void)start
{
  // 此处省略若干行...
  [self registerExtraModules];
  // Initialize all native modules that cannot be loaded lazily
  (void)[self _initializeModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO];
  [self registerExtraLazyModules];
  // 此处省略若干行...
}

然后每个native module都会被转换成RCTModuleData对象,RCTModuleData描述了这个module的具体信息,moduleData会被缓存在_moduleDataByName字典中和_moduleDataByID数组,以及_moduleClassesByID数组中。至此,我们就已经在运行collect了所有需要导出给JS的native module。

代码语言:txt
AI代码解释
复制
- (NSArray<RCTModuleData *> *)_registerModulesForClasses:(NSArray<Class> *)moduleClasses
                                        lazilyDiscovered:(BOOL)lazilyDiscovered
{

  NSArray *moduleClassesCopy = [moduleClasses copy];
  NSMutableArray<RCTModuleData *> *moduleDataByID = [NSMutableArray arrayWithCapacity:moduleClassesCopy.count];
  for (Class moduleClass in moduleClassesCopy) {
    NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
    RCTModuleData *moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self];

    _moduleDataByName[moduleName] = moduleData;
    [_moduleClassesByID addObject:moduleClass];
    [moduleDataByID addObject:moduleData];
  }
  [_moduleDataByID addObjectsFromArray:moduleDataByID];

  return moduleDataByID;
}

RCT_EXPORT_METHOD(Native方法暴露给JS)

代码语言:txt
AI代码解释
复制
#define RCT_EXPORT_METHOD(method) \
  RCT_REMAP_METHOD(, method)
  
#define RCT_REMAP_METHOD(js_name, method) \
 _RCT_EXTERN_REMAP_METHOD(js_name, method, NO) \
 - (void)method RCT_DYNAMIC;

#define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
  + (const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
    static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
    return &config; \
  }

#define RCT_CONCAT2(A, B) A ## B
#define RCT_CONCAT(A, B) RCT_CONCAT2(A, B)

通过上面一系列的宏调用不难看出,RCT_EXPORT_METHOD最终做了2件事:

1.定义一个对象方法

2.定义一个静态方法,该方法名的格式是+(const RCTMethodInfo *)__rct_export__+js_name+___LINE__+__COUNTER__

如果没有js_name参数,那么最终的格式就是+(const RCTMethodInfo *)__rct_export__+___LINE__+__COUNTER__

比如:+(const RCTMethodInfo *)__rct_export__131 其中13是__LINE__,1是__COUNTER__

而这个方法的实现是这样的:

代码语言:txt
AI代码解释
复制
+(const RCTMethodInfo *)__rct_export__+js_name+__LINE__+__COUNTER__ {
    static RCTMethodInfo config = {
        js_name,
        method,
        is_blocking_synchronous_method
    }
    return &config;
}

可以看出,最终把这个方法包装成了一个RCTMethodInfo对象,在运行时RN会扫描所有导出的native module中以__rct_export__开头的方法。

以上只是说了native module和method是如何导出的,这些模块和方法的注册将会在另一篇文章中介绍。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
偏最小二乘回归(PLSR)和主成分回归(PCR)分析光谱数据|附代码数据
此示例显示如何在matlab中应用偏最小二乘回归(PLSR)和主成分回归(PCR),并讨论这两种方法的有效性(点击文末“阅读原文”获取完整代码数据)。
拓端
2022/11/02
1.4K0
偏最小二乘回归(PLSR)和主成分回归(PCR)
此示例显示如何在matlab中应用偏最小二乘回归(PLSR)和主成分回归(PCR),并讨论这两种方法的有效性。当存在大量预测变量时,PLSR和PCR都是对响应变量建模的方法,并且这些预测变量高度相关或甚至共线。两种方法都将新的预测变量(称为组件)构建为原始预测变量的线性组合,但它们以不同的方式构造这些组件。PCR创建组件来解释预测变量中观察到的变异性,而根本不考虑响应变量。另一方面,PLSR确实将响应变量考虑在内,因此通常会导致模型能够使用更少的组件来适应响应变量。
拓端
2020/08/04
2.3K0
偏最小二乘回归(PLSR)和主成分回归(PCR)
Python用偏最小二乘回归Partial Least Squares,PLS分析桃子近红外光谱数据可视化
PLS,即偏最小二乘(Partial Least Squares),是一种广泛使用的回归技术,用于帮助客户分析近红外光谱数据。如果您对近红外光谱学有所了解,您肯定知道近红外光谱是一种次级方法,需要将近红外数据校准到所要测量的参数的主要参考数据上。这个校准只需在第一次进行。一旦校准完成且稳健,就可以继续使用近红外数据预测感兴趣参数的值。
拓端
2023/11/27
8730
【视频讲解】偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响|附代码数据
本文将通过视频讲解,展示如何用偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响,并结合Python用偏最小二乘回归Partial Least Squares,PLS分析桃子近红外光谱数据可视化实例和R语言结构方程模型SEM、路径分析房价和犯罪率数据、预测智力影响的代码数据,为读者提供一套完整的实践数据分析流程(点击文末“阅读原文”获取完整代码数据)。
拓端
2025/01/15
3320
【视频讲解】偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响|附代码数据
Matlab中的偏最小二乘法(PLS)回归模型,离群点检测和变量选择|附代码数据
本文建立偏最小二乘法(PLS)回归(PLSR)模型,以及预测性能评估。为了建立一个可靠的模型,我们还实现了一些常用的离群点检测和变量选择方法,可以去除潜在的离群点和只使用所选变量的子集来 "清洗 "你的数据。
拓端
2023/01/10
1.2K0
Matlab中的偏最小二乘法(PLS)回归模型,离群点检测和变量选择|附代码数据
本文建立偏最小二乘法(PLS)回归(PLSR)模型,以及预测性能评估。为了建立一个可靠的模型,我们还实现了一些常用的离群点检测和变量选择方法,可以去除潜在的离群点和只使用所选变量的子集来 "清洗 "你的数据 。
拓端
2022/11/21
8440
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据|附代码数据
最近我们被客户要求撰写关于高维数据惩罚回归方法的研究报告,包括一些图形和统计输出。
拓端
2023/04/12
8580
偏最小二乘法(PLS)
PLS是交叉分解的第二个重要算法族,在python等语言中也有相应的包实现。一般如果需要在研究多个自变量与因变量的关系话题中,绕不过去的就是多元回归,包括以线性关系为主的多元线性回归和高次多项式为主的响应面分析,众所周知,在多元线性回归中一般可以用最小二乘法计算每个自变量的系数,这一理论比较成熟,其系数矩阵
用户7506105
2021/08/06
2.7K0
R语言中的偏最小二乘回归PLS-DA
今天,我们将 在Arcene数据集上执行PLS-DA, 其中包含100个观察值和10,000个解释变量。
拓端
2023/12/02
3860
R语言中的偏最小二乘回归PLS-DA
R语言中的岭回归、套索回归、主成分回归:线性模型选择和正则化
在本课程中,我们将考虑一些线性模型的替代拟合方法,除了通常的  普通最小二乘法。这些替代方法有时可以提供更好的预测准确性和模型可解释性。
拓端
2020/08/21
3.3K0
R语言中的偏最小二乘回归PLS-DA
主成分回归(PCR)的方法 本质上是使用第一个方法的普通最小二乘(OLS)拟合来自预测变量的主成分(PC)(点击文末“阅读原文”获取完整代码数据)。
拓端
2025/01/01
1510
R语言中的偏最小二乘回归PLS-DA
R语言中的偏最小二乘回归PLS-DA
今天,我们将 在Arcene数据集上执行PLS-DA,  其中包含100个观察值和10,000个解释变量。
拓端
2020/09/25
1.9K0
R语言实现偏最小二乘回归法 partial least squares (PLS)回归
偏最小二乘回归是一种回归形式 。  当使用pls时,新 的线性组合有助于解释模型中的自变量和因变量。
拓端
2020/09/25
3.9K0
拓端tecdat|R语言 PCA(主成分分析),CA(对应分析)夫妻职业差异和马赛克图可视化
主成分分析法是数据挖掘中常用的一种降维算法,是Pearson在1901年提出的,再后来由hotelling在1933年加以发展提出的一种多变量的统计方法,其最主要的用途在于“降维”,通过析取主成分显出的最大的个别差异,也可以用来削减回归分析和聚类分析中变量的数目,与因子分析类似。
拓端
2021/06/29
8530
R语言中的偏最小二乘PLS回归算法
我将围绕结构方程建模(SEM)技术进行一些咨询,以解决独特的业务问题。我们试图识别客户对各种产品的偏好,传统的回归是不够的,因为数据集的高度分量以及变量的多重共线性。PLS是处理这些有问题的数据集的强大而有效的方法。
拓端
2020/08/28
1.6K0
R语言PCA主成分、lasso、岭回归降维分析全球气候变化对各国土地面积影响
机器学习在环境监测领域的应用,着眼于探索全球范围内的环境演化规律,人类与自然生态之间的关系以及环境变化对人类生存的影响。
拓端
2023/01/31
4150
高维变量选择专题|R、Python用HOLP、Lasso、SCAD、PCR、ElasticNet实例合集分析企业财务、糖尿病
本专题合集聚焦高维数据场景下的稀疏建模与变量选择,通过 R 语言与 Python 双平台技术栈,系统解析企业财务分析与基因数据挖掘两大领域的核心方法论。合集深度整合 HOLP-Adaptive Lasso 二阶段模型、SCAD 平滑剪切绝对偏差惩罚、主成分回归(PCR)、弹性网络(Elastic Net)等前沿算法,结合国泰安 2021 年信息技术企业财务数据集与哺乳动物基因表达数据集,构建完整的高维数据分析闭环(点击文末“阅读原文”获取完整代码、数据、文档)。
拓端
2025/03/20
1720
高维变量选择专题|R、Python用HOLP、Lasso、SCAD、PCR、ElasticNet实例合集分析企业财务、糖尿病
数据分析师需要掌握的10个统计学知识
Glassdoor利用庞大的就业数据和员工反馈信息,统计了美国25个最佳职位排行榜,其中,数据科学家排名第一。这个工作的重要性可见一斑。毫无疑问,数据科学家所做的事情是不断变化和发展的。随着机器学习的普遍应用,数据科学家们将继续在创新和技术进步浪潮中独领风骚。
1480
2019/05/22
1.4K0
当今最火10大统计算法,你用过几个?
为什么学习统计学习?理解不同技术背后的理念非常重要,它可以帮助你了解如何使用以及什么时候使用。同时,准确评估一种方法的性能也非常重要,因为它能告诉我们某种方法在特定问题上的表现。此外,统计学习也是一个很有意思的研究领域,在科学、工业和金融领域都有重要的应用。最后,统计学习是训练现代数据科学家的基础组成部分。 统计学习方法的经典研究主题包括: 线性回归模型 感知机 k 近邻法 朴素贝叶斯法 决策树 Logistic 回归与最大熵模型 支持向量机 提升方法 EM 算法 隐马尔可夫模型 条件随机场 之后我将介绍
BestSDK
2018/03/02
1.2K0
当今最火10大统计算法,你用过几个?
RDA-PLS:多数据集关联分析
在现代微生物组学分析中,高通量的测试方法使得研究者可以一次性获取大量的数据信息,这时候所获得的数据里可能存在大量“冗余”;此外,在实际操作中,研究人员为避免遗漏重要的系统特征,往往倾向于较周到的选取测试指标,这些变量之间也很可能存在多重共线性。因此,在大数据量的多个数据集之间进行分析时,常常难以有效的进行数据挖掘。
SYSU星空
2022/05/05
9871
RDA-PLS:多数据集关联分析
推荐阅读
偏最小二乘回归(PLSR)和主成分回归(PCR)分析光谱数据|附代码数据
1.4K0
偏最小二乘回归(PLSR)和主成分回归(PCR)
2.3K0
Python用偏最小二乘回归Partial Least Squares,PLS分析桃子近红外光谱数据可视化
8730
【视频讲解】偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响|附代码数据
3320
Matlab中的偏最小二乘法(PLS)回归模型,离群点检测和变量选择|附代码数据
1.2K0
Matlab中的偏最小二乘法(PLS)回归模型,离群点检测和变量选择|附代码数据
8440
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据|附代码数据
8580
偏最小二乘法(PLS)
2.7K0
R语言中的偏最小二乘回归PLS-DA
3860
R语言中的岭回归、套索回归、主成分回归:线性模型选择和正则化
3.3K0
R语言中的偏最小二乘回归PLS-DA
1510
R语言中的偏最小二乘回归PLS-DA
1.9K0
R语言实现偏最小二乘回归法 partial least squares (PLS)回归
3.9K0
拓端tecdat|R语言 PCA(主成分分析),CA(对应分析)夫妻职业差异和马赛克图可视化
8530
R语言中的偏最小二乘PLS回归算法
1.6K0
R语言PCA主成分、lasso、岭回归降维分析全球气候变化对各国土地面积影响
4150
高维变量选择专题|R、Python用HOLP、Lasso、SCAD、PCR、ElasticNet实例合集分析企业财务、糖尿病
1720
数据分析师需要掌握的10个统计学知识
1.4K0
当今最火10大统计算法,你用过几个?
1.2K0
RDA-PLS:多数据集关联分析
9871
相关推荐
偏最小二乘回归(PLSR)和主成分回归(PCR)分析光谱数据|附代码数据
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档