RCTViewManager and RCTUIManager

1. RCTViewManager

1.1 RCTViewManager 实现了接口RCTBridgeModule

 @interface RCTViewManager : NSObject <RCTBridgeModule>

1.2 宏RCT_EXPORT_VIEW_PROPERTY

from file RCTViewManager.m

 RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)

以上宏展开为:

 // RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)
+ (NSString *)getPropConfigView_accessibilityLabel { return @"NSString"; }
- (void)set_accessibilityLabel:(id)json forView:(UIView *)view withDefaultView:(UIView *)defaultView
{ if ((json && !RCTSetProperty(view, @"accessibilityLabel", @selector(NSString:), json))
|| (!json && !RCTCopyProperty(view, defaultView, @"accessibilityLabel")))
{
do {
if (RCTLogLevelError >= RCTLogLevelMustFix) {
do {
BOOL pass = ((__objc_no) != );
if ( && !pass){
[[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__)
file:@("/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m")
lineNumber:
description:@"%@ does not have setter for `%s` property", [view class], "accessibilityLabel"];
}
_RCTAssertFormat(pass, "/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m",
, __func__,
@"%@ does not have setter for `%s` property",
[view class], "accessibilityLabel");
} while ();
}
_RCTLogFormat(RCTLogLevelError, "/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m", , @"%@ does not have setter for `%s` property",
[view class], "accessibilityLabel");
} while ();
}
}

3. RCTBridgeModule接口

 /**
* Provides the interface needed to register a bridge module.
*/
@protocol RCTBridgeModule <NSObject>

RCTBridgeModule: 定义注册一个“bridge module”所需要的接口。

bridge module: 实现接口RCTBridgeModule的类被称为“bridge module”, 这些模块可以被注册到 RCTBridge 中。

3.1 RCTBridgeModule.h中提供的宏定义

宏定义以及描述
RCT_EXPORT_MODULE(js_name)

#define RCT_EXPORT_MODULE(js_name) \

RCT_EXTERN void RCTRegisterModule(Class); \

+ (NSString *)moduleName { return @#js_name; } \

+ (void)load { RCTRegisterModule([self class]); }

RCT_EXPORT_METHOD(method)

#define RCT_EXPORT_METHOD(method) \

RCT_REMAP_METHOD(, method)

RCT_REMAP_METHOD(js_name, method)

#define RCT_REMAP_METHOD(js_name, method) \

RCT_EXTERN_REMAP_METHOD(js_name, method) \

- (void)method

RCT_EXTERN_MODULE(objc_name, objc_supername)

#define RCT_EXTERN_MODULE(objc_name, objc_supername) \

RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername)

RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername)

#define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \

objc_name : objc_supername \

@end \

@interface objc_name (RCTExternModule) <RCTBridgeModule> \

@end \

@implementation objc_name (RCTExternModule) \

RCT_EXPORT_MODULE(js_name)

RCT_EXTERN_METHOD(method)

#define RCT_EXTERN_METHOD(method) \

RCT_EXTERN_REMAP_METHOD(, method)

RCT_EXTERN_REMAP_METHOD(js_name, method)

#define RCT_EXTERN_REMAP_METHOD(js_name, method) \

+ (NSArray *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \

return @[@#js_name, @#method]; \

} \

   

A): RCT_EXPORT_MODULE(js_name): 将BridgeModule注册到bridge中。该宏依赖函数:

RCTRegisterModule(), 下面看一下该函数的实现: (RCTBridge.m)

 void RCTRegisterModule(Class moduleClass)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTModuleClasses = [[NSMutableArray alloc] init];
}); RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], // 1
@"%@ does not conform to the RCTBridgeModule protocol",
NSStringFromClass(moduleClass)); // Register module
[RCTModuleClasses addObject:moduleClass];
}

RCTRegisterModule()仅仅是将Class对象添加到了一个数组类型的静态变量RCTModuleClasses中.

1: “bridge module” 必须实现接口 RCTBridgeModule 。

RCT_EXPORT_MODULE(js_name)

"The optional js_name argument will be used as the JS module name. If omitted, the JS module name will

match the Objective-C class name. "

B): RCT_EXPORT_METHOD(method) 宏  

Wrap the parameter line of your method implementation with this macro to

expose it to JS.

用宏 RCT_EXPORT_METHOD() 来处理要导出到JS中的接口:

 RCT_EXPORT_METHOD(createTimer:(NSNumber *)callbackID
duration:(NSTimeInterval)jsDuration
jsSchedulingTime:(NSDate *)jsSchedulingTime
repeats:(BOOL)repeats)

以上宏 RCT_EXPORT_METHOD()展开为:

 + (NSArray *)__rct_export__1720 { return @[@"", @"createTimer:(NSNumber *)callbackID duration:(NSTimeInterval)jsDuration jsSchedulingTime:(NSDate *)jsSchedulingTime repeats:(BOOL)repeats"]; } 
- (void)createTimer:(NSNumber *)callbackID duration:(NSTimeInterval)jsDuration jsSchedulingTime:(NSDate *)jsSchedulingTime repeats:(BOOL)repeats

导入到JS的接口为: "NativeModules.ModuleName.createTimer(number)", 只有Selector第一个:以前的部分。

TODO: JavaScript Promise  Javascript.Promise

C): RCT_REMAP_METHOD(js_name, method) 宏

该宏和RCT_EXPORT_METHOD(method)类似, 只不过通过该宏可以指定导入到JS的接口名称。

D): 宏 RCT_EXTERN_MODULE 和 RCT_EXTERN_REMAP_MODULE

RCT_EXTERN_MODULE(objc_name, objc_supername)

RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername)

"Use this macro in a private Objective-C implementation file to automatically register an

external module with the bridge when it loads."  'private Object-C implementation'是指Objective-C中的类别(category)。

 /* MyModuleExport.m:
*
* #import "RCTBridgeModule.h"
*
* @interface RCT_EXTERN_MODULE(MyModule, NSObject)
*
* RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b)
*
* @end
*
* This will now expose MyModule and the method to JavaScript via
* `NativeModules.MyModule.doSomething`
*/
#define RCT_EXTERN_MODULE(objc_name, objc_supername) \
RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername) /**
* Like RCT_EXTERN_MODULE, but allows setting a custom JavaScript name.
*/
#define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \
objc_name : objc_supername \
@end \
@interface objc_name (RCTExternModule) <RCTBridgeModule> \
@end \
@implementation objc_name (RCTExternModule) \
RCT_EXPORT_MODULE(js_name)

E: 宏RCT_EXTERN_METHOD 和 RCT_EXTERN_REMAP_METHOD

3.2 RCTBridgeModule的接口方法

RCTBridgeModule提供的接口用来注册"Bridge Module" 模块。

3.3 实现RCTBridgeModule接口的类

实现接口RCTBridgeModule的类都是 "Bridge Module" 模块类,这些类的实例称为"Bridge Module"。

3.4 "Bridge Module" 初始化

RCTBatchedBridge类的方法initModules 对Native "Bridge Module" 进行了初始化。


Reference

1. React-Native Source Code

iOS.ReactNative-3-about-viewmanager-uimanager-and-bridgemodule的更多相关文章

  1. iOS React-Native入门指南之HelloWorld

    React-native 作为facebook开源项目,最近是火的一塌糊涂,它采用node.js能够写ios和android的native界面代码,简直是太酷了.支持动态更新,而且appstore 提 ...

  2. 新闻头条应用源码ios版

    <ignore_js_op>      源码下载:http://code.662p.com/view/13343.html     作者ymcao,源码TopNewsIOS,新闻头条IOS ...

  3. React-Native入门指南之HelloWorld

    iOS React-Native入门指南之HelloWorld React-native 作为facebook开源项目,最近是火的一塌糊涂,它采用node.js能够写ios和android的nativ ...

  4. React Native之code-push的热更新(ios android)

    React Native之code-push的热更新(ios android) React Native支持大家用React Native技术开发APP,并打包生成一个APP.在动态更新方面React ...

  5. react-native开发总结

    项目地址:http://liu12fei08fei.github.io/blog/41react-native.html 说明 • 项目总结代码地址 • 从项目开始启动(2018-07-02)到项目进 ...

  6. react-native 常用命令

    创建项目 react-native init AwesomeProject //AwesomeProject是项目名 启动 Node.js web server react-native start ...

  7. React Native环境配置

    React Native环境配置 史上最全Windows版本搭建安装React Native环境配置 配置过React Native 环境的都知道,在Windows React Native环境配置有 ...

  8. window环境下搭建react native及相关插件

    可以先浏览一下中文翻译的开发文档具体了解一下关于React Native,想要查看官方文档可以点http://facebook.github.io/react-native/docs/getting- ...

  9. React Native获取组件位置和大小

    RN页面中定位或滚动操作时,需要获取元素的大小和位置信息,有几种常用的方法 获取设备屏幕的宽高 import {Dimensions} from 'react-native'; var {height ...

  10. CodePush热更新组件详细接入教程

    CodePush热更新组件详细接入教程 什么是CodePush CodePush是一个微软开发的云服务器.通过它,开发者可以直接在用户的设备上部署手机应用更新.CodePush相当于一个中心仓库,开发 ...

随机推荐

  1. 基于纹理的图片检索及demo(未启动)

    基于纹理的图片检索及demo(未启动)

  2. SE要有政治能力

    不光是SE,任何人都需要政治能力. 那么,什么是政治能力?政治能力就是让周围的人跟你一起,一条心,完成你想干的事情的能力. 我们任何人,生活也好,工作也好,学习也好,都不是一个人孤单进行的,都是通过几 ...

  3. 使用Windows上的Eclipse 远程调试 linux下的Tomcat

    1:修改Linux上Tomcat的catalina.sh,第一行添加declare -x CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_sock ...

  4. Ubuntu 查看和杀死进程

    1.ps -e 2.netstat -antup 3.kill pid 4.pgrep 进程名 5.killall  进程名 6.kill -9 pid

  5. MySQL事件 Events

    MySQL事件 Events   一.关键字: EVENT   二.语法: CREATE EVENT? [IF NOT EXISTS ] //如果不存在则创建 event_name? ON SCHED ...

  6. Visual Studio 2013 always switches source control plugin to Git and disconnect TFS

      A few days ago, I've been facing a strange behavior with Visual Studio 2013.   No matter what solu ...

  7. iOS 解压打包静态库命令

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Hannotate SC" } p.p2 { margin: 0.0px ...

  8. MySQL_监控用户下单地址没有就近仓库配送情况_20161215

    如果用户所在的地址位于A市场,A市场所就近的仓库应该为a,通过监控发现用户下单后配送仓库的不是a而是b仓库发货,这就会引起物流成本的增加. 因此对客户下单挑选最近的仓库进行监控是很有必要的 #C041 ...

  9. C# 一些知识点总结(一)_继承,多态,集合,关键字...

    内存中的三大存储区域:栈.堆.静态存储区域 new 关键字:new帮助我们做了三件事:1)在内存中开辟一块空间(开辟内存空间)2) 在开辟的空间中创建对象3)调用对象的构造函数进行初始化对象所以构造函 ...

  10. JQuery动画效果

    jquery动画效果常用方法 1.show()显示效果语法:show(speed,callback)Number/String,Function speend为动画执行时间,单位为毫秒.也可以为slo ...