zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    shell编程:字符串处理方式
    shell编程:变量替换
    export的用法
    docker stack利用secrets启动wordpress
    docker swarm创建swarm集群
    docker x509: certificate has expired or is not yet valid
    docker-compose的scale的用法
    字符串函数-unquote()函数
    Sass-@each
    Sass-@while
  • 原文地址:https://www.cnblogs.com/cwgk/p/4745815.html
Copyright © 2011-2022 走看看