XiaoKL

iOS.ReactNative-3-about-viewmanager-uimanager-and-bridgemodule

RCTViewManager and RCTUIManager

1. RCTViewManager

1.1 RCTViewManager 实现了接口RCTBridgeModule

1 @interface RCTViewManager : NSObject <RCTBridgeModule>

1.2 宏RCT_EXPORT_VIEW_PROPERTY

from file RCTViewManager.m  

1 RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)

以上宏展开为: 

 1 // RCT_EXPORT_VIEW_PROPERTY(accessibilityLabel, NSString)
 2 + (NSString *)getPropConfigView_accessibilityLabel { return @"NSString"; }
 3 - (void)set_accessibilityLabel:(id)json forView:(UIView *)view withDefaultView:(UIView *)defaultView
 4 { if ((json && !RCTSetProperty(view, @"accessibilityLabel", @selector(NSString:), json))
 5       || (!json && !RCTCopyProperty(view, defaultView, @"accessibilityLabel")))
 6   {
 7     do {
 8       if (RCTLogLevelError >= RCTLogLevelMustFix) {
 9         do {
10           BOOL pass = ((__objc_no) != 0);
11           if (1 && !pass){
12               [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__)
13                                                                       file:@("/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m")
14                                                                 lineNumber:94
15                                                                description:@"%@ does not have setter for `%s` property", [view class], "accessibilityLabel"];
16           }
17           _RCTAssertFormat(pass, "/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m",
18                            94, __func__,
19                            @"%@ does not have setter for `%s` property",
20                            [view class], "accessibilityLabel");
21         } while (0);
22       }
23     _RCTLogFormat(RCTLogLevelError, "/Users/XiaoKL/react-native/AwesomeProject/node_modules/react-native/React/Views/RCTViewManager.m", 94, @"%@ does not have setter for `%s` property",
24                   [view class], "accessibilityLabel");
25     } while (0);
26   }
27 }

 

 

 

 

3. RCTBridgeModule接口

1 /**
2  * Provides the interface needed to register a bridge module.
3  */
4 @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)

 1 void RCTRegisterModule(Class moduleClass)
 2 {
 3   static dispatch_once_t onceToken;
 4   dispatch_once(&onceToken, ^{
 5     RCTModuleClasses = [[NSMutableArray alloc] init];
 6   });
 7 
 8   RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], // 1
 9             @"%@ does not conform to the RCTBridgeModule protocol",
10             NSStringFromClass(moduleClass));
11 
12   // Register module
13   [RCTModuleClasses addObject:moduleClass];
14 }

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中的接口:

1 RCT_EXPORT_METHOD(createTimer:(NSNumber *)callbackID
2                   duration:(NSTimeInterval)jsDuration
3                   jsSchedulingTime:(NSDate *)jsSchedulingTime
4                   repeats:(BOOL)repeats)

 以上宏 RCT_EXPORT_METHOD()展开为:

1 + (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)。

 1  
 2 /* MyModuleExport.m:
 3  *
 4  *   #import "RCTBridgeModule.h"
 5  *
 6  *   @interface RCT_EXTERN_MODULE(MyModule, NSObject)
 7  *
 8  *   RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b)
 9  *
10  *   @end
11  *
12  * This will now expose MyModule and the method to JavaScript via
13  * `NativeModules.MyModule.doSomething`
14  */
15 #define RCT_EXTERN_MODULE(objc_name, objc_supername) \
16   RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername)
17 
18 /**
19  * Like RCT_EXTERN_MODULE, but allows setting a custom JavaScript name.
20  */
21 #define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \
22   objc_name : objc_supername \
23   @end \
24   @interface objc_name (RCTExternModule) <RCTBridgeModule> \
25   @end \
26   @implementation objc_name (RCTExternModule) \
27   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

posted on 2016-02-18 14:04  XiaoKL  阅读(975)  评论(0编辑  收藏  举报

导航