React Native新架构之iOS端初始化源码分析
React Native新架构之iOS端初始化源码分析
前言
注意,本文是基于React Native 0.83版本源码进行分析。有了前面几篇Android端分析文章打基础,再来理解iOS端就易如反掌了。总的来说,iOS端的实现要比Android端简单太多了,这是因为Android端的Java/Kotlin 都是运行在Java的虚拟机环境中,其与C++通信要经过JNI,并不如OC与C++互调那么简单直接。此外,RN基于Android的Gradle构建机制,也使问题更加复杂。
初始化流程
React Native的iOS端相比于安卓端要简单很多。现在我们基于Swift入口来分析一下初始化流程。首先找到RN源码工程中的测试工程,打开源码react-native/private/helloworld/ios/HelloWorld/AppDelegate.swift:
import React // React Native 核心模块
import ReactAppDependencyProvider // Codegen 生成的依赖提供者
import React_RCTAppDelegate // AppDelegate 相关类
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
// 1: 创建 ReactNativeDelegate
let delegate = ReactNativeDelegate()
// 2: 创建 RCTReactNativeFactory
let factory = RCTReactNativeFactory(delegate: delegate)
// 3: 配置依赖提供者(Codegen 生成的模块)
delegate.dependencyProvider = RCTAppDependencyProvider()
// 保持强引用
reactNativeDelegate = delegate
reactNativeFactory = factory
// 4: 配置开发菜单(仅 DEBUG 模式)
#if DEBUG
let devMenuConfiguration = RCTDevMenuConfiguration(
devMenuEnabled: true,
shakeGestureEnabled: true,
keyboardShortcutsEnabled: true
)
reactNativeFactory?.devMenuConfiguration = devMenuConfiguration
#endif
// 5: 创建主窗口
window = UIWindow(frame: UIScreen.main.bounds)
// 6: 启动 React Native
factory.startReactNative(
withModuleName: "HelloWorld",
in: window,
launchOptions: launchOptions
)
return true
}
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
// 旧架构兼容(新架构中会调用 bundleURL)
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
// 提供 JS Bundle 的 URL
override func bundleURL() -> URL? {
#if DEBUG
// 开发模式:从 Metro 开发服务器加载
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
// 生产模式:从 App Bundle 加载
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
Swift 新架构使用 @main 注解作为应用入口,无需 main.m 或 main.swift 文件。ReactNativeDelegate 继承自 RCTDefaultReactNativeFactoryDelegate,负责提供 Bundle URL 和自定义配置。
这里RCTAppDependencyProvider是Objective-C++代码,这是为了方便与C++互调。源码tcode/react-native/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm:
@interface RCTReactNativeFactory () <
RCTComponentViewFactoryComponentProvider, // Fabric 组件提供者
RCTHostDelegate, // RCTHost 代理
RCTJSRuntimeConfiguratorProtocol, // JS Runtime 配置
RCTTurboModuleManagerDelegate> // TurboModule 管理器代理
@end
@implementation RCTReactNativeFactory
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate
{
return [self initWithDelegate:delegate releaseLevel:Stable];
}
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel
{
if (self = [super init]) {
self.delegate = delegate;
[self _setUpFeatureFlags:releaseLevel];
// 设置默认颜色空间
[RCTColorSpaceUtils applyDefaultColorSpace:[self defaultColorSpace]];
RCTEnableTurboModule(YES);
// 创建 RCTRootViewFactory
self.rootViewFactory = [self createRCTRootViewFactory];
// 设置第三方 Fabric 组件提供者
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
return self;
}
可以看到RCTReactNativeFactory的构造逻辑非常简单,但它实现了四个关键协议,这使得它可以作为多个子系统的代理。
先重点看一下createRCTRootViewFactory方法的实现,这是一个关键方法,同时设置了大量的回调 Block 来桥接代理模式:
- (RCTRootViewFactory *)createRCTRootViewFactory
{
__weak __typeof(self) weakSelf = self;
// 1. 创建 Bundle URL 提供者 Block
RCTBundleURLBlock bundleUrlBlock = ^{
auto *strongSelf = weakSelf;
return strongSelf.bundleURL;
};
// 2. 创建配置对象(新架构默认全部启用)
RCTRootViewFactoryConfiguration *configuration =
[[RCTRootViewFactoryConfiguration alloc] initWithBundleURLBlock:bundleUrlBlock
newArchEnabled:YES
turboModuleEnabled:YES
bridgelessEnabled:YES];
// 省略旧架构代码......
// 3.配置根视图自定义回调
configuration.customizeRootView = ^(UIView *_Nonnull rootView) {
[weakSelf.delegate customizeRootView:(RCTRootView *)rootView];
};
// 4.配置 Bundle URL 获取回调
configuration.sourceURLForBridge = ^NSURL *_Nullable(RCTBridge *_Nonnull bridge)
{
// 新架构:直接使用 bundleURL,不再依赖 bridge
return [weakSelf.delegate bundleURL];
};
// 5.配置 Bundle 加载回调(支持进度)
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:onProgress:onComplete:)]) {
configuration.loadSourceForBridgeWithProgress =
^(RCTBridge *_Nonnull bridge,
RCTSourceLoadProgressBlock _Nonnull onProgress,
RCTSourceLoadBlock _Nonnull loadCallback) {
// 新架构:使用 loadBundleAtURL 替代旧的 loadSourceForBridge
[weakSelf.delegate loadBundleAtURL:self.bundleURL onProgress:onProgress onComplete:loadCallback];
};
}
// 6.配置无进度的 Bundle 加载回调
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
configuration.loadSourceForBridge = ^(RCTBridge *_Nonnull bridge, RCTSourceLoadBlock _Nonnull loadCallback) {
// 新架构:使用 loadBundleAtURL,进度回调为空
[weakSelf.delegate loadBundleAtURL:self.bundleURL
onProgress:^(RCTLoadingProgress *progressData) {
}
onComplete:loadCallback];
};
}
// 7.设置 JS Runtime 代理
configuration.jsRuntimeConfiguratorDelegate = self;
// 8.创建并返回 RCTRootViewFactory
return [[RCTRootViewFactory alloc] initWithTurboModuleDelegate:self hostDelegate:self configuration:configuration];
}
这里的大概流程是非常清楚的,主要就是设置了四个协议的代理。我们将流程绘制成一个关系图:
┌─────────────────────────────────────────────────────────────────────────┐
│ RCTReactNativeFactory │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 实现协议: │ │
│ │ • RCTTurboModuleManagerDelegate → TurboModule 类/实例查找 │ │
│ │ • RCTHostDelegate → Host 生命周期 + Bundle 加载 │ │
│ │ • RCTJSRuntimeConfiguratorProtocol → JS Runtime 工厂创建 │ │
│ │ • RCTComponentViewFactoryComponentProvider → Fabric 组件注册 │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ createRCTRootViewFactory() 中设置: │ │
│ │ • initWithTurboModuleDelegate: self ← RCTTurboModuleManagerDelegate│
│ │ • hostDelegate: self ← RCTHostDelegate │
│ │ • jsRuntimeConfiguratorDelegate: self ← RCTJSRuntimeConfiguratorProtocol│
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 初始化时设置: │ │
│ │ • thirdPartyFabricComponentsProvider = self │ │
│ │ ← RCTComponentViewFactoryComponentProvider │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
RCTTurboModuleManagerDelegate
主要负责 TurboModule 的类查找和实例创建,源码react-native/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.h:
@class RCTBridgeProxy;
@class RCTTurboModuleManager;
@class RCTDevMenuConfigurationDecorator;
@protocol RCTTurboModuleManagerDelegate <NSObject>
/**
* 给定模块名称,返回其实际类。如果返回 nil,则执行基本的 ObjC 类查找
*/
- (Class)getModuleClassFromName:(const char *)name;
/**
* 给定一个模块类,为其提供一个实例。如果返回值为 nil,则使用默认初始化器
*/
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass;
@optional
/**
* 此方法用于获取一个工厂对象,该对象可以创建 `facebook::react::TurboModule` 实例。
* 实现 `RCTTurboModuleProvider` 接口的类必须是 Objective-C 类,以便我们可以使用代码生成工具对其进行动态初始化。
*/
- (id<RCTModuleProvider>)getModuleProvider:(const char *)name;
/**
* 创建一个 TurboModule 实例,而无需依赖任何 ObjC++ 模块实例
*/
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:
(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;
- (void)installJSBindings:(facebook::jsi::Runtime &)runtime;
- (void)invalidate;
@end
再来看看RCTReactNativeFactory 中的实现:
#pragma mark - RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
#if RN_DISABLE_OSS_PLUGIN_HEADER
return RCTTurboModulePluginClassProvider(name);
#else
// 先尝试从 delegate 获取
if ([_delegate respondsToSelector:@selector(getModuleClassFromName:)]) {
Class moduleClass = [_delegate getModuleClassFromName:name];
if (moduleClass != nil) {
return moduleClass;
}
}
return RCTCoreModulesClassProvider(name);
#endif
}
- (nullable id<RCTModuleProvider>)getModuleProvider:(const char *)name
{
if ([_delegate respondsToSelector:@selector(getModuleProvider:)]) {
return [_delegate getModuleProvider:name];
}
return nil;
}
// 创建纯 C++ TurboModule
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
if ([_delegate respondsToSelector:@selector(getTurboModule:jsInvoker:)]) {
return [_delegate getTurboModule:name jsInvoker:jsInvoker];
}
return facebook::react::DefaultTurboModules::getTurboModule(name, jsInvoker);
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
#if USE_OSS_CODEGEN
if (self.delegate.dependencyProvider == nil) {
[NSException raise:@"ReactNativeFactoryDelegate dependencyProvider is nil"
format:@"Delegate must provide a valid dependencyProvider"];
}
#endif
if ([_delegate respondsToSelector:@selector(getModuleInstanceFromClass:)]) {
id<RCTTurboModule> moduleInstance = [_delegate getModuleInstanceFromClass:moduleClass];
if (moduleInstance != nil) {
return moduleInstance;
}
}
// 使用默认方式创建(通过 dependencyProvider)
return RCTAppSetupDefaultModuleFromClass(moduleClass, self.delegate.dependencyProvider);
}
RCTHostDelegate
主要负责 RCTHost 的生命周期和 Bundle 加载。源码react-native/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h:
NS_ASSUME_NONNULL_BEGIN
@class RCTFabricSurface;
@class RCTHost;
@class RCTModuleRegistry;
@class RCTDevMenuConfiguration;
@protocol RCTTurboModuleManagerDelegate;
typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
// Runtime API
@protocol RCTHostDelegate <NSObject>
// Host 启动完成通知
- (void)hostDidStart:(RCTHost *)host;
@optional
// 需要在主线程初始化的模块列表
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
// 加载 Bundle(支持进度回调)
- (void)loadBundleAtURL:(NSURL *)sourceURL
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback;
@end
NS_ASSUME_NONNULL_END
查看RCTReactNativeFactory 中的实现:
#pragma mark - RCTHostDelegate
- (void)hostDidStart:(RCTHost *)host
{
if ([_delegate respondsToSelector:@selector(hostDidStart:)]) {
[_delegate hostDidStart:host];
}
}
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup
{
#if RN_DISABLE_OSS_PLUGIN_HEADER
return RCTTurboModulePluginUnstableModulesRequiringMainQueueSetup();
#else
return self.delegate.dependencyProvider
? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.delegate.dependencyProvider)
: @[];
#endif
}
RCTJSRuntimeConfiguratorProtocol
主要负责创建 JS Runtime 工厂,源码react-native/packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h:
NS_ASSUME_NONNULL_BEGIN
// Forward declarations for umbrella headers.
// In implementations, import `<react/runtime/JSRuntimeFactoryCAPI.h>` to obtain the actual type.
typedef void *JSRuntimeFactoryRef;
@protocol RCTJSRuntimeConfiguratorProtocol
// 创建 JS Runtime 工厂(通常返回 Hermes)
- (JSRuntimeFactoryRef)createJSRuntimeFactory;
@end
NS_ASSUME_NONNULL_END
查看RCTReactNativeFactory 中的实现:
#pragma mark - RCTJSRuntimeConfiguratorProtocol
- (JSRuntimeFactoryRef)createJSRuntimeFactory
{
// 委托给用户的 delegate
return [_delegate createJSRuntimeFactory];
}
RCTComponentViewFactoryComponentProvider
主要负责提供第三方 Fabric 组件,源码react-native/packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.h:
/**
* 可用于向 Fabric 提供第三方组件的协议。
* Fabric 将检查此映射表,以确定是否存在需要注册的组件。
*/
@protocol RCTComponentViewFactoryComponentProvider <NSObject>
/**
* 返回一个第三方组件字典,其中 `key` 是组件处理程序,`value` 是一个符合 `RCTComponentViewProtocol` 协议的类
*/
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
@end
查看RCTReactNativeFactory 中的实现:
#pragma mark - RCTComponentViewFactoryComponentProvider
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
// 先尝试从 delegate 获取
if ([_delegate respondsToSelector:@selector(thirdPartyFabricComponents)]) {
return _delegate.thirdPartyFabricComponents;
}
// 回退到 dependencyProvider(Codegen 生成)
return self.delegate.dependencyProvider ? self.delegate.dependencyProvider.thirdPartyFabricComponents : @{};
}
RCTDefaultReactNativeFactoryDelegate
以上协的很多方法的实现,其实也是代理给RCTReactNativeFactory 中的delegate对象。此delegate也就是我们最开始自定义的ReactNativeDelegate实例。其也是继承自RCTDefaultReactNativeFactoryDelegate,现在分析一下此类的实现,源码react-native/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm:
@implementation RCTDefaultReactNativeFactoryDelegate
@synthesize dependencyProvider;
// 抽象方法:子类必须实现
- (NSURL *_Nullable)sourceURLForBridge:(nonnull RCTBridge *)bridge
{
[NSException raise:@"RCTBridgeDelegate::sourceURLForBridge not implemented"
format:@"Subclasses must implement a valid sourceURLForBridge method"];
return nil;
}
- (UIViewController *)createRootViewController
{
return [UIViewController new];
}
- (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController
{
rootViewController.view = rootView;
}
- (JSRuntimeFactoryRef)createJSRuntimeFactory
{
#if USE_THIRD_PARTY_JSC != 1
return jsrt_create_hermes_factory();
#endif
}
- (void)customizeRootView:(RCTRootView *)rootView
{
// Override point for customization after application launch.
}
- (RCTColorSpace)defaultColorSpace
{
return RCTColorSpaceSRGB;
}
- (NSURL *_Nullable)bundleURL
{
[NSException raise:@"RCTAppDelegate::bundleURL not implemented"
format:@"Subclasses must implement a valid getBundleURL method"];
return nullptr;
}
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.thirdPartyFabricComponents : @{};
}
- (void)hostDidStart:(RCTHost *)host
{
}
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup
{
return (self.dependencyProvider != nullptr)
? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.dependencyProvider)
: @[];
}
- (nullable id<RCTModuleProvider>)getModuleProvider:(const char *)name
{
NSString *providerName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.moduleProviders[providerName] : nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return facebook::react::DefaultTurboModules::getTurboModule(name, jsInvoker);
}
#pragma mark - RCTArchConfiguratorProtocol
- (BOOL)newArchEnabled
{
return YES;
}
- (BOOL)bridgelessEnabled
{
return YES;
}
- (BOOL)fabricEnabled
{
return YES;
}
- (BOOL)turboModuleEnabled
{
return YES;
}
- (Class)getModuleClassFromName:(const char *)name
{
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return nullptr;
}
- (void)loadSourceForBridge:(RCTBridge *)bridge
onProgress:(RCTSourceLoadProgressBlock)onProgress
onComplete:(RCTSourceLoadBlock)loadCallback
{
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge] onProgress:onProgress onComplete:loadCallback];
}
@end
React Native 启动
对于以上四个协议以及代理,我们已经有了大概认识,现在应该把视线拉回AppDelegate中的初始化流程,继续分析startReactNative方法的实现,它对应的OC方法名应该是startReactNativeWithModuleName:
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
launchOptions:(NSDictionary *_Nullable)launchOptions
{
[self startReactNativeWithModuleName:moduleName inWindow:window initialProperties:nil launchOptions:launchOptions];
}
- (void)startReactNativeWithModuleName:(NSString *)moduleName
inWindow:(UIWindow *_Nullable)window
initialProperties:(NSDictionary *_Nullable)initialProperties
launchOptions:(NSDictionary *_Nullable)launchOptions
{
// 1. 通过 RootViewFactory 创建根视图
UIView *rootView = [self.rootViewFactory viewWithModuleName:moduleName
initialProperties:initialProperties
launchOptions:launchOptions
devMenuConfiguration:self.devMenuConfiguration];
// 2. 创建 RootViewController
UIViewController *rootViewController = [_delegate createRootViewController];
// 3. 设置根视图
[_delegate setRootView:rootView toRootViewController:rootViewController];
// 4. 配置窗口并显示
window.rootViewController = rootViewController;
[window makeKeyAndVisible];
}
可以看到,流程十分清楚,我们继续跟踪viewWithModuleName方法实现。
RCTHost (ReactHost)初始化
查看源码react-native/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm:
- (UIView *)viewWithModuleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initProps
launchOptions:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
// 1. 初始化 ReactHost
[self initializeReactHostWithLaunchOptions:launchOptions devMenuConfiguration:devMenuConfiguration];
// 2. 创建 Fabric Surface
RCTFabricSurface *surface = [self.reactHost createSurfaceWithModuleName:moduleName
initialProperties:initProps ? initProps : @{}];
// 3. 创建 SurfaceHostingProxyRootView
RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView =
[[RCTSurfaceHostingProxyRootView alloc] initWithSurface:surface];
surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor];
if (_configuration.customizeRootView != nil) {
// 4. 自定义根视图
_configuration.customizeRootView(surfaceHostingProxyRootView);
}
return surfaceHostingProxyRootView;
}
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
// Enable TurboModule interop by default in Bridgeless mode
RCTEnableTurboModuleInterop(YES);
RCTEnableTurboModuleInteropBridgeProxy(YES);
[self createReactHostIfNeeded:launchOptions devMenuConfiguration:devMenuConfiguration];
return;
}
- (void)createReactHostIfNeeded:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
if (self.reactHost) {
return;
}
self.reactHost = [self createReactHost:launchOptions devMenuConfiguration:devMenuConfiguration];
}
- (RCTHost *)createReactHost:(NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
__weak __typeof(self) weakSelf = self;
RCTHost *reactHost =
[[RCTHost alloc] initWithBundleURLProvider:self->_configuration.bundleURLBlock
hostDelegate:_hostDelegate
turboModuleManagerDelegate:_turboModuleManagerDelegate
jsEngineProvider:^std::shared_ptr<facebook::react::JSRuntimeFactory>() {
return [weakSelf createJSRuntimeFactory];
}
launchOptions:launchOptions
devMenuConfiguration:devMenuConfiguration];
// 设置 Bundle URL 提供者
[reactHost setBundleURLProvider:^NSURL *() {
return [weakSelf bundleURL];
}];
// 启动 ReactHost
[reactHost start];
return reactHost;
}
RCTInstance 初始化
继续跟踪RCTHost的start方法。源码react-native/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm:
- (void)start
{
// 1. 设置 Bundle URL
if (_bundleURLProvider) {
[self _setBundleURL:_bundleURLProvider()];
}
// 2. 设置 Inspector Target(用于调试)
auto &inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getFuseboxEnabled() && !_inspectorPageId.has_value()) {
_inspectorTarget =
facebook::react::jsinspector_modern::HostTarget::create(*_inspectorHostDelegate, [](auto callback) {
RCTExecuteOnMainQueue(^{
callback();
});
});
__weak RCTHost *weakSelf = self;
_inspectorPageId = facebook::react::jsinspector_modern::getInspectorInstance().addPage(
"React Native Bridgeless",
/* vm */ "",
[weakSelf](std::unique_ptr<facebook::react::jsinspector_modern::IRemoteConnection> remote)
-> std::unique_ptr<facebook::react::jsinspector_modern::ILocalConnection> {
RCTHost *strongSelf = weakSelf;
if (!strongSelf) {
// This can happen if we're about to be dealloc'd. Reject the connection.
return nullptr;
}
return strongSelf->_inspectorTarget->connect(std::move(remote));
},
{.nativePageReloads = true, .prefersFuseboxFrontend = true});
}
if (_instance) {
RCTLogWarn(
@"RCTHost should not be creating a new instance if one already exists. This implies there is a bug with how/when this method is being called.");
[_instance invalidate];
}
// 3. 创建 RCTInstance
_instance = [[RCTInstance alloc] initWithDelegate:self
jsRuntimeFactory:[self _provideJSEngine]
bundleManager:_bundleManager
turboModuleManagerDelegate:_turboModuleManagerDelegate
moduleRegistry:_moduleRegistry
parentInspectorTarget:_inspectorTarget.get()
launchOptions:_launchOptions
devMenuConfiguration:_devMenuConfiguration];
// 4. 通知代理 Host 已启动
[_hostDelegate hostDidStart:self];
}
继续查看RCTInstance的构造实现,源码react-native/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm:
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
bundleManager:(RCTBundleManager *)bundleManager
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)tmmDelegate
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
parentInspectorTarget:(jsinspector_modern::HostTarget *)parentInspectorTarget
launchOptions:(nullable NSDictionary *)launchOptions
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration
{
if (self = [super init]) {
// 性能监控初始化
_performanceLogger = [RCTPerformanceLogger new];
registerPerformanceLoggerHooks(_performanceLogger);
[_performanceLogger markStartForTag:RCTPLReactInstanceInit];
// 保存外部传入的关键依赖
_delegate = delegate;
_jsRuntimeFactory = jsRuntimeFactory;
_appTMMDelegate = tmmDelegate;
_jsThreadManager = [RCTJSThreadManager new];
// 开发菜单配置
_devMenuConfigurationDecorator =
#if RCT_DEV_MENU
[[RCTDevMenuConfigurationDecorator alloc] initWithDevMenuConfiguration:devMenuConfiguration];
#else
nil;
#endif
_parentInspectorTarget = parentInspectorTarget;
// JS 模块调用器配置(设置 Bridgeless 模式下的 JS 模块方法调用器)
{
__weak __typeof(self) weakSelf = self;
[_bridgeModuleDecorator.callableJSModules
setBridgelessJSModuleMethodInvoker:^(
NSString *moduleName, NSString *methodName, NSArray *args, dispatch_block_t onComplete) {
[weakSelf callFunctionOnJSModule:moduleName method:methodName args:args];
if (onComplete) {
[weakSelf
callFunctionOnBufferedRuntimeExecutor:[onComplete](facebook::jsi::Runtime &_) { onComplete(); }];
}
}];
}
_launchOptions = launchOptions;
// 内存警告监听
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_handleMemoryWarning)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
// 启动核心初始化
[self _start];
}
return self;
}
接下来,我们来看整个初始化过程的核心方法_start实现:
- (void)_start
{
// 1.设置定时器系统
auto objCTimerRegistry = std::make_unique<ObjCTimerRegistry>();
auto timing = objCTimerRegistry->timing;
auto *objCTimerRegistryRawPtr = objCTimerRegistry.get();
auto timerManager = std::make_shared<TimerManager>(std::move(objCTimerRegistry));
objCTimerRegistryRawPtr->setTimerManager(timerManager);
__weak __typeof(self) weakSelf = self;
auto onJsError = [=](jsi::Runtime &runtime, const JsErrorHandler::ProcessedError &error) {
[weakSelf _handleJSError:error withRuntime:runtime];
};
// 2.创建 ReactInstance (C++ 层)
_reactInstance = std::make_unique<ReactInstance>(
_jsRuntimeFactory->createJSRuntime(_jsThreadManager.jsMessageThread),
_jsThreadManager.jsMessageThread,
timerManager,
onJsError,
_parentInspectorTarget);
_valid = true;
// 3.设置 RuntimeExecutor
RuntimeExecutor bufferedRuntimeExecutor = _reactInstance->getBufferedRuntimeExecutor();
timerManager->setRuntimeExecutor(bufferedRuntimeExecutor);
auto jsCallInvoker = make_shared<RuntimeSchedulerCallInvoker>(_reactInstance->getRuntimeScheduler());
// 省略旧架构......
// 4.创建 TurboModuleManager
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridgeProxy:bridgeProxy
bridgeModuleDecorator:_bridgeModuleDecorator
delegate:self
jsInvoker:jsCallInvoker
devMenuConfigurationDecorator:_devMenuConfigurationDecorator];
#if RCT_DEV
/**
* 实例化 DevMenu 会产生副作用,即通过 RCTDevMenu 注册
* CMD + d、CMD + i 和 CMD + n 的快捷键。
* 因此,启用 TurboModules 时,我们必须手动创建此NativeModule。
*/
[_turboModuleManager moduleForName:"RCTDevMenu"];
#endif // end RCT_DEV
// 初始化 RCTModuleRegistry,以便 TurboModules 可以引用其他 TurboModules
[_bridgeModuleDecorator.moduleRegistry setTurboModuleRegistry:_turboModuleManager];
if (ReactNativeFeatureFlags::enableEagerMainQueueModulesOnIOS()) {
/**
* 某些原生模块需要在主线程上捕获 UIKit 对象。
* 因此,请在此处的主队列上开始初始化这些模块。JavaScript 线程将等待这些模块初始化完成后,才会执行 JavaScript 代码包。
*/
NSArray<NSString *> *modulesRequiringMainQueueSetup = [_delegate unstableModulesRequiringMainQueueSetup];
std::shared_ptr<std::mutex> mutex = std::make_shared<std::mutex>();
std::shared_ptr<std::condition_variable> cv = std::make_shared<std::condition_variable>();
std::shared_ptr<bool> isReady = std::make_shared<bool>(false);
_waitUntilModuleSetupComplete = ^{
std::unique_lock<std::mutex> lock(*mutex);
cv->wait(lock, [isReady] { return *isReady; });
};
// TODO(T218039767): 将性能日志记录功能集成到主队列模块初始化过程中
RCTExecuteOnMainQueue(^{
for (NSString *moduleName in modulesRequiringMainQueueSetup) {
[self->_bridgeModuleDecorator.moduleRegistry moduleForName:[moduleName UTF8String]];
}
RCTScreenSize();
RCTScreenScale();
RCTSwitchSize();
std::lock_guard<std::mutex> lock(*mutex);
*isReady = true;
cv->notify_all();
});
}
RCTLogSetBridgelessModuleRegistry(_bridgeModuleDecorator.moduleRegistry);
RCTLogSetBridgelessCallableJSModules(_bridgeModuleDecorator.callableJSModules);
// 5.创建 ContextContainer
auto contextContainer = std::make_shared<ContextContainer>();
[_delegate didCreateContextContainer:contextContainer];
// 插入核心模块
contextContainer->insert(
"RCTImageLoader", facebook::react::wrapManagedObject([_turboModuleManager moduleForName:"RCTImageLoader"]));
contextContainer->insert(
"RCTEventDispatcher",
facebook::react::wrapManagedObject([_turboModuleManager moduleForName:"RCTEventDispatcher"]));
contextContainer->insert("RCTBridgeModuleDecorator", facebook::react::wrapManagedObject(_bridgeModuleDecorator));
contextContainer->insert(RuntimeSchedulerKey, std::weak_ptr<RuntimeScheduler>(_reactInstance->getRuntimeScheduler()));
contextContainer->insert("RCTBridgeProxy", facebook::react::wrapManagedObject(bridgeProxy));
// 6.创建 SurfacePresenter
_surfacePresenter = [[RCTSurfacePresenter alloc]
initWithContextContainer:contextContainer
runtimeExecutor:bufferedRuntimeExecutor
bridgelessBindingsExecutor:std::optional(_reactInstance->getUnbufferedRuntimeExecutor())];
// 这使得模块中的 RCTViewRegistry 能够通过其 viewForReactTag 方法返回 UIView 对象
__weak RCTSurfacePresenter *weakSurfacePresenter = _surfacePresenter;
[_bridgeModuleDecorator.viewRegistry_DEPRECATED setBridgelessComponentViewProvider:^UIView *(NSNumber *reactTag) {
RCTSurfacePresenter *strongSurfacePresenter = weakSurfacePresenter;
if (strongSurfacePresenter == nil) {
return nil;
}
return [strongSurfacePresenter findComponentViewWithTag_DO_NOT_USE_DEPRECATED:reactTag.integerValue];
}];
// 7.创建DisplayLink (用于调用计时器回调函数)
_displayLink = [RCTDisplayLink new];
auto &inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
ReactInstance::JSRuntimeFlags options = {
.isProfiling = inspectorFlags.getIsProfilingBuild(),
.runtimeDiagnosticFlags = [RCTInstanceRuntimeDiagnosticFlags() UTF8String]};
// 8.初始化 JS Runtime 并加载 Bundle
_reactInstance->initializeRuntime(options, [=](jsi::Runtime &runtime) {
__strong __typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// 安装 TurboModule JS 绑定
[strongSelf->_turboModuleManager installJSBindings:runtime];
// 绑定 Native Logger
facebook::react::bindNativeLogger(runtime, [](const std::string &message, unsigned int logLevel) {
_RCTLogJavaScriptInternal(static_cast<RCTLogLevel>(logLevel), [NSString stringWithUTF8String:message.c_str()]);
});
// 安装 Native Component Registry 绑定
RCTInstallNativeComponentRegistryBinding(runtime);
// 通知代理 Runtime 已初始化
[strongSelf->_delegate instance:strongSelf didInitializeRuntime:runtime];
// 设置 DisplayLink
id<RCTDisplayLinkModuleHolder> moduleHolder = [[RCTBridgelessDisplayLinkModuleHolder alloc] initWithModule:timing];
[strongSelf->_displayLink registerModuleForFrameUpdates:timing withModuleHolder:moduleHolder];
[strongSelf->_displayLink addToRunLoop:[NSRunLoop currentRunLoop]];
// 尝试同步加载bundle包,如果失败则回退到异步加载。
[strongSelf->_performanceLogger markStartForTag:RCTPLScriptDownload];
[strongSelf _loadJSBundle:[strongSelf->_bridgeModuleDecorator.bundleManager bundleURL]];
});
[_performanceLogger markStopForTag:RCTPLReactInstanceInit];
}
JS Bundle 加载
继续查看_loadJSBundle方法的实现:
- (void)_loadJSBundle:(NSURL *)sourceURL
{
#if RCT_DEV_MENU && __has_include(<React/RCTDevLoadingViewProtocol.h>)
{
// 显示加载视图
id<RCTDevLoadingViewProtocol> loadingView =
(id<RCTDevLoadingViewProtocol>)[_turboModuleManager moduleForName:"DevLoadingView"];
[loadingView showWithURL:sourceURL];
}
#endif
__weak __typeof(self) weakSelf = self;
// 通过代理加载 Bundle
[_delegate loadBundleAtURL:sourceURL
onProgress:^(RCTLoadingProgress *progressData) {
__typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
#if RCT_DEV_MENU && __has_include(<React/RCTDevLoadingViewProtocol.h>)
id<RCTDevLoadingViewProtocol> loadingView =
(id<RCTDevLoadingViewProtocol>)[strongSelf->_turboModuleManager moduleForName:"DevLoadingView"];
[loadingView updateProgress:progressData];
#endif
}
onComplete:^(NSError *error, RCTSource *source) {
__typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (error) {
[strongSelf handleBundleLoadingError:error];
return;
}
// _loadScriptFromSource 函数的回调函数需要 DevSettings 模块,因此需要提前进行初始化。
RCTDevSettings *const devSettings =
(RCTDevSettings *)[strongSelf->_turboModuleManager moduleForName:"DevSettings"];
// 加载脚本
[strongSelf _loadScriptFromSource:source];
// 仅在开发环境中启用热模块重载功能。
[strongSelf->_performanceLogger markStopForTag:RCTPLScriptDownload];
[devSettings setupHMRClientWithBundleURL:sourceURL];
#if RCT_DEV
[strongSelf _logOldArchitectureWarnings];
#endif
}];
}
- (void)_loadScriptFromSource:(RCTSource *)source
{
std::lock_guard<std::mutex> lock(_invalidationMutex);
if (!_valid) {
return;
}
auto script = std::make_unique<NSDataBigString>(source.data);
const auto *url = deriveSourceURL(source.url).UTF8String;
auto beforeLoad = [waitUntilModuleSetupComplete = self->_waitUntilModuleSetupComplete](jsi::Runtime &_) {
if (waitUntilModuleSetupComplete) {
waitUntilModuleSetupComplete();
}
};
auto afterLoad = [](jsi::Runtime &_) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTInstanceDidLoadBundle" object:nil];
};
// 在 ReactInstance 中执行脚本
_reactInstance->loadScript(std::move(script), url, beforeLoad, afterLoad);
}
Surface 创建与启动
现在,我们把视线拉回viewWithModuleName方法中,继续分析后面的createSurfaceWithModuleName方法的实现。源码RCTHost.mm:
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)properties
{
return [self createSurfaceWithModuleName:moduleName mode:DisplayMode::Visible initialProperties:properties];
}
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName
mode:(DisplayMode)displayMode
initialProperties:(NSDictionary *)properties
{
// 1. 创建 FabricSurface
RCTFabricSurface *surface = [[RCTFabricSurface alloc] initWithSurfacePresenter:self.surfacePresenter
moduleName:moduleName
initialProperties:properties];
// 2. 设置显示模式
surface.surfaceHandler.setDisplayMode(displayMode);
// 3. 附加 Surface
[self _attachSurface:surface];
__weak RCTFabricSurface *weakSurface = surface;
// 在 JS Bundle 执行完成后,使用BufferedRuntimeExecutor启动Surface
[_instance callFunctionOnBufferedRuntimeExecutor:[weakSurface](facebook::jsi::Runtime &_) { [weakSurface start]; }];
return surface;
}
总结
初始化的大概流程:
┌─────────────────────────────────────────────────────────────────┐
│ Swift 应用层 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ AppDelegate ││
│ │ ├── reactNativeDelegate: ReactNativeDelegate ││
│ │ └── reactNativeFactory: RCTReactNativeFactory ││
│ └─────────────────────────────────────────────────────────────┘│
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ReactNativeDelegate : RCTDefaultReactNativeFactoryDelegate ││
│ │ ├── bundleURL() → URL? ││
│ │ └── dependencyProvider: RCTAppDependencyProvider ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Factory 层 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ RCTReactNativeFactory ││
│ │ ├── delegate: RCTReactNativeFactoryDelegate ││
│ │ ├── rootViewFactory: RCTRootViewFactory ││
│ │ └── startReactNative(withModuleName:in:) ││
│ └─────────────────────────────────────────────────────────────┘│
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ RCTRootViewFactory ││
│ │ ├── reactHost: RCTHost ││
│ │ ├── view(withModuleName:) → UIView ││
│ │ └── createReactHost() → RCTHost ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Host 层 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ RCTHost ││
│ │ ├── instance: RCTInstance ││
│ │ ├── bundleManager: RCTBundleManager ││
│ │ ├── start() ││
│ │ └── createSurface(withModuleName:) → RCTFabricSurface ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Instance 层 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ RCTInstance ││
│ │ ├── reactInstance: ReactInstance (C++) ││
│ │ ├── turboModuleManager: RCTTurboModuleManager ││
│ │ ├── surfacePresenter: RCTSurfacePresenter ││
│ │ ├── displayLink: RCTDisplayLink ││
│ │ └── _start() ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ C++ Runtime 层 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ReactInstance (C++) ││
│ │ ├── jsRuntime: jsi::Runtime (Hermes) ││
│ │ ├── runtimeScheduler: RuntimeScheduler ││
│ │ ├── timerManager: TimerManager ││
│ │ ├── initializeRuntime() ││
│ │ └── loadScript() ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘