91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react native 0.50 源碼解析 再出發 持續更新

發布時間:2020-07-24 11:13:43 來源:網絡 閱讀:8451 作者:magicyaa 欄目:移動開發

1.核心類

1.1 RCTRootView

一個RCTRootView持有一個RCTBridge成員變量

RCTRootView : UIView
  RCTBridge *bridge;
  UIViewController *reactViewController;
  UIView *contentView;
  UIView *loadingView;

1.2 RCTBridge

一個RCTBridge持有一個RCTCxxBridge成員變量

RCTBridge.h
 @interface RCTBridge : NSObject <RCTInvalidating>

RCTBridge+Private.h
@interface RCTBridge ()
   RCTBridge *batchedBridge;
@end

RCTBridge.m
- (Class)bridgeClass
  return [RCTCxxBridge class];

- (void)setUp
  Class bridgeClass = self.bridgeClass;
  self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
  [self.batchedBridge start];

1.3 RCTCxxBridge

RCTCxxBridge繼承自RCTBridge,是RCTBridge的一個變量,擁有弱引用parentBridge指向RCTBridge變量

RCTBridge+Private.h
@interface RCTCxxBridge:RCTBridge

RCTCxxBridge.mm
@interface RCTCxxBridge()
RCTBridge *parentBridge;
@end
//@interface ViewController()后面 ,@end前面的是類擴展,就是創建本類中似有的屬性和方法。其他類不能使用的

2.核心流程

2.1 native注冊模塊表

一個native類需要向js暴露的過程,就是向全局靜態數組RCTModuleClasses注冊自身class的過程。工程啟動后,自動生成全局靜態數組RCTModuleClasses,儲存注冊的class

######RCTBridge
聲明全局靜態數組:
static NSMutableArray<Class> *RCTModuleClasses;

######native類
需要做到以下兩點,
1.實現RCTBridgeModule協議
2.在m文件中放置RCT_EXPORT_MODULE()代碼。

RCT_EXPORT_MODULE宏給native類置入load函數。native類在加載過程中,可以自動向RCTModuleClasses注冊自身Class。實例如下

ClassA.h
#import <React/RCTBridgeModule.h>
@interface ClassA <RCTBridgeModule>
@end

ClassA.m
RCT_EXPORT_MODULE() ==>
extern __attribute__((visibility("default"))) 
void RCTRegisterModule(Class);  
+ (void)load { RCTRegisterModule(self); }

========================================
宏定義
RCTBridgeModule.h
#define RCT_EXPORT_MODULE(js_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+ (NSString *)moduleName { return @#js_name; } \
+ (void)load { RCTRegisterModule(self); }

#define RCT_EXPORT_MODULE(js_name) RCT_EXTERN void RCTRegisterModule(Class);  + (NSString *)moduleName { return @#js_name; }  + (void)load { RCTRegisterModule(self); }

RCTDefindes.h
#define RCT_EXTERN extern __attribute__((visibility("default")))

注冊
RCTBridge.m
static NSMutableArray<Class> *RCTModuleClasses;
void RCTRegisterModule(Class moduleClass)
   [RCTModuleClasses addObject:moduleClass];

2.2 RCTCxxBridge初始化模塊表

RCTCxxBridge有三個成員變量,_moduleDataByName,_moduleDataByID,_moduleClassesByID

RCTCxxBridge
NSMutableDictionary<NSString *, RCTModuleData *> *_moduleDataByName; //字典,name:RCTModuleData鍵值對
NSMutableArray<RCTModuleData *> *_moduleDataByID; //RCTModuleData數組
NSMutableArray<Class> *_moduleClassesByID; //Class數組
- (void)start 
  [self _initModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO];

- (void)_initModules:(NSArray<id<RCTBridgeModule>> *)modules
   withDispatchGroup:(dispatch_group_t)dispatchGroup
    lazilyDiscovered:(BOOL)lazilyDiscovered
  NSArray<RCTModuleData *> *moduleDataById = [self registerModulesForClasses:modules]; //將modules轉換成RCTCxxBridge的模塊組

- (NSArray<RCTModuleData *> *)registerModulesForClasses:(NSArray<Class> *)moduleClasses
   for (Class moduleClass in moduleClasses) {
      _moduleDataByName[moduleName] = moduleData;
      [_moduleClassesByID addObject:moduleClass];
      [moduleDataByID addObject:moduleData];
   }
   [_moduleDataByID addObjectsFromArray:moduleDataByID];

2.3 RCTCxxBridge 加載/執行JS資源

 - (void)start 
     [self loadSource:^(NSError *error, RCTSource *source)
           {sourceCode = source.data;}]  // 加載JS
     [strongSelf executeSourceCode:sourceCode sync:NO]; //執行JS

- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad onProgress:(RCTSourceLoadProgressBlock)onProgress
     發送通知RCTBridgeWillDownloadScriptNotification
     RCTSourceLoadBlock onSourceLoad = ^(NSError *error, RCTSource *source) 
     {
            發送通知RCTBridgeDidDownloadScriptNotification:RCTSource
     }
    [RCTJavaScriptLoader loadBundleAtURL:self.bundleURL onProgress:onProgress onComplete:^(NSError *error, RCTSource *source)
     {
          onSourceLoad(error, source);
     }

- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync
   - (void)executeApplicationScript:(NSData *)script
                             url:(NSURL *)url
                           async:(BOOL)async
  dispatch_block_t completion = ^{
          [self _flushPendingCalls];
          廣播通知RCTJavaScriptDidLoadNotification
          [self ensureOnJavaScriptThread:^{
             [self->_displayLink addToRunLoop:[NSRunLoop currentRunLoop]];
          }];
     }

- (void)executeApplicationScript:(NSData *)script
                             url:(NSURL *)url
                           async:(BOOL)async
  if (isRAMBundle(script))
      self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr),
                                            sourceUrlStr.UTF8String, !async);
  else if (self->_reactInstance)
      self->_reactInstance->loadScriptFromString(std::make_unique<NSDataBigString>(script),
                                                 sourceUrlStr.UTF8String, !async);

- (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules
    |=== - (NSArray<RCTModuleData *> *)registerModulesForClasses:(NSArray<Class> *)moduleClasses
          |---for (Class moduleClass in moduleClasses) 
          {
              NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
              moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self];

          }

[RCTCxxBridge registerExtraModules]
  • (void)start
    |--- 廣播通知---
    RCTJavaScriptWillStartLoadingNotification:@{@"bridge": self}
    |--- 新建并啟動js線程 _jsThread
    |--- 注冊moduleClass---
    [self registerExtraModules];
    [self _initModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO];
    |--- 創建工廠并配置---
    std::shared_ptr<JSExecutorFactory> executorFactory;
    |--- 加載js資源---
    [self loadSource:^(NSError error, RCTSource source)
    |--- 執行js---
    [strongSelf executeSourceCode:sourceCode sync:NO];

啟動

[AppDelegate didFinishLaunchingWithOptions]
|---獲取jsCodeLocation
|---[RCTRootView initWithBundleURL..]
    |---[RCTBridge alloc+init]
        |---設置變量:delegate,bundleURL,moduleProvider, launchOptions
        |---[RCTBridge setUp]
            |---設置變量:bundleURL
            |---[RCTCxxBridge alloc+init]  --> RCTBridge.batchedBridge
            |---[RCTCxxBridge start]

    |---[RCTRootView initWithBridge:...]
          |---注冊三個通知,如下
          |---[self bundleFinishedLoading:([_bridge batchedBridge] ?: _bridge)];
                |---RCTRootContentView alloc
                |---[self runApplication:bridge];
                       |---[bridge enqueueJSCall:@"AppRegistry"
                 method:@"runApplication"
                   args:@[moduleName, appParameters]
             completion:NULL];
                |---insertSubview:_contentView

RCTRootView 繼承自UIView,內含RCTBridge變量,初始化參數BundleURL/moduleName/Properties/launchOptions。初始化的時候,初始化RCTBridge變量,自我初始化。自我初始化過程:注冊三個通知,RCTJavaScriptWillStartLoadingNotification/RCTJavaScriptDidLoadNotification/RCTContentDidAppearNotification

RCTBridge native call js

[RCTBridge enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray *)args completion:(dispatch_block_t)completion]
|---[self.batchedBridge enqueueJSCall:module method:method args:args completion:completion];

RCTCxxBridge 成員:
_moduleClassesByID
_moduleDataByID
_moduleDataByName 可變字典:string(moduleName):RCTModuleData(Data)的鍵值隊
RCTCxxBridge native call js,可以從任意線程中調起

RCTBridge  
- (void)setUp
   URL轉換
   self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
   [self.batchedBridge start];

- (void)registerAdditionalModuleClasses:(NSArray<Class> *)modules
   [self.batchedBridge registerAdditionalModuleClasses:modules];
RCTJavaScriptLoader  
+ (void)loadBundleAtURL:(NSURL *)scriptURL onProgress:(RCTSourceLoadProgressBlock)onProgress onComplete:(RCTSourceLoadBlock)onComplete
|---NSData *data = [self attemptSynchronousLoadOfBundleAtURL:scriptURL
                                          runtimeBCVersion:JSNoBytecodeFileFormatVersion
                                              sourceLength:&sourceLength
                                                     error:&error];
|---onComplete(nil, RCTSourceCreate(scriptURL, data, sourceLength));

+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
                               runtimeBCVersion:(int32_t)runtimeBCVersion
                                   sourceLength:(int64_t *)sourceLength
                                          error:(NSError **)error
|---FILE *bundle = fopen(scriptURL.path.UTF8String, "r");
    size_t readResult = fread(&header, sizeof(header), 1, bundle);
[RCTCxxBridge enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray *)args completion:(dispatch_block_t)completion]
|---

NSInvocation 調用 native 方法

調用原生代碼生成UI控件

RCTUIManager RCT_EXPORT_METHOD(createView:(nonnull NSNumber *)reactTag
                                 viewName:(NSString *)viewName
                                  rootTag:(nonnull NSNumber *)rootTag
                                    props:(NSDictionary *)props)
|---createViewBlock
      |---[RCTComponentData createViewWithTag:reactTag];
            |--- [self.manager view]   
                 #此處self.manager是實際需要生成的UI類,如RCTTextView等
                 #所以,所有RN的原生UI都必須實現view功能
      |---RCTUIManager->_viewRegistry[reactTag] = preliminaryCreatedView;  
          #保存至注冊數組,reactTag:preliminaryCreatedView
          #RCTUIManager->_viewRegistry 
          # {1 = "<RCTRootContentView: 0x7faf12c015d0; reactTag: 1; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x60000024eaf0>; layer = <CALayer: 0x6040002376c0>>";
          # 2 = "<UIView: 0x7faf12f0a6d0; frame = (0 0; 0 0); layer = <CALayer: 0x600000621300>>";}
Instance C++ 類
void Instance::loadRAMBundle(std::unique_ptr<RAMBundleRegistry> bundleRegistry,
                             std::unique_ptr<const JSBigString> startupScript,
                             std::string startupScriptSourceURL,
                             bool loadSynchronously)

RCTModuleMethod C++ 類
通過NSInvocation動態調用相應的OC模塊方法

- (id)invokeWithBridge:(RCTBridge *)bridge
                module:(id)module
             arguments:(NSArray *)arguments
   [self processMethodSignature];   //set blocks 
   block(bridge, index, RCTNilIfNull(json(arguments))   //set arguments
   [_invocation invokeWithTarget:module];   //調起函數
   [_invocation getReturnValue:&returnValue];   //獲取返回值

RN 支持功能
tabbar,nagigator,text,image,數據庫?,ar?,真機調試日志?,網絡,攝像頭拍照,圖片剪裁,音頻,視頻,下載,

添加RN庫

tabbar
官方組件 TabBarIOS,TabBarIOS.Item,只支持iOS,棄用
流行組件

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长乐市| 株洲县| 望城县| 青神县| 灵川县| 怀远县| 沙湾县| 安化县| 霍城县| 磐安县| 夏津县| 吉木乃县| 滁州市| 绥阳县| 阳曲县| 石台县| 阿克苏市| 房产| 汾西县| 阳城县| 土默特右旗| 司法| 银川市| 尼木县| 天峨县| 漯河市| 无棣县| 友谊县| 定兴县| 阳江市| 晋中市| 会泽县| 新民市| 昌宁县| 乐亭县| 枝江市| 阿尔山市| 西昌市| 淮南市| 东莞市| 两当县|