diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 163fe44fd..d2fdc429a 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -1412,4 +1412,17 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR return _reactInstance->getJavaScriptContext(); } +- (void)invokeAsync:(std::function&&)func +{ + __block auto retainedFunc = std::move(func); + __weak __typeof(self) weakSelf = self; + [self _runAfterLoad:^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf->_reactInstance == nullptr) { + return; + } + strongSelf->_reactInstance->invokeAsync(std::move(retainedFunc)); + }]; +} + @end diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index b39567e4d..464dde426 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -39,6 +39,7 @@ using namespace facebook::react; @interface RCTBridge () - (std::shared_ptr)jsMessageThread; +- (void)invokeAsync:(std::function &&)func; @end @interface RCTSurfacePresenter () @@ -220,12 +221,12 @@ using namespace facebook::react; auto runtime = (facebook::jsi::Runtime *)((RCTCxxBridge *)_batchedBridge).runtime; - RuntimeExecutor runtimeExecutor = - [runtime, messageQueueThread](std::function &&callback) { - messageQueueThread->runOnQueue([runtime, callback = std::move(callback)]() { - callback(*runtime); - }); - }; + RuntimeExecutor runtimeExecutor = [self, runtime](std::function &&callback) { + // For now, ask the bridge to queue the callback asynchronously to ensure that + // it's not invoked too early, e.g. before the bridge is fully ready. + // Revisit this after Fabric/TurboModule is fully rolled out. + [((RCTCxxBridge *)_batchedBridge) invokeAsync:[runtime, callback = std::move(callback)]() { callback(*runtime); }]; + }; EventBeatFactory synchronousBeatFactory = [runtimeExecutor]() { return std::make_unique(runtimeExecutor);