Skip to content

Commit

Permalink
do not iterate through moduleData array to handle UIManager batch com…
Browse files Browse the repository at this point in the history
…pletion

Summary:
Changelog: [iOS][Deprecated] - Deprecating RCTBridgeModule batchDidComplete and adding configuration to disable it

batchDidComplete is used for the UIManager to initiate a layout and mount after a callback has been initiated by the bridge. however, we iterate through the whole module array in order to get this single UIManager, which is unnecessary. this also increases risk of a crash because the module array is shared between threads.

Differential Revision: D62600034
  • Loading branch information
philIip authored and facebook-github-bot committed Sep 12, 2024
1 parent d0121a6 commit 55f0ffa
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
3 changes: 3 additions & 0 deletions packages/react-native/React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ void RCTSetTurboModuleInteropBridgeProxyLogLevel(RCTBridgeProxyLoggingLevel logL
BOOL RCTTurboModuleInteropForAllTurboModulesEnabled(void);
void RCTEnableTurboModuleInteropForAllTurboModules(BOOL enabled);

BOOL RCTBridgeModuleBatchDidCompleteDisabled(void);
void RCTDisableBridgeModuleBatchDidComplete(BOOL disabled);

typedef enum {
kRCTGlobalScope,
kRCTGlobalScopeUsingRetainJSCallback,
Expand Down
11 changes: 11 additions & 0 deletions packages/react-native/React/Base/RCTBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,17 @@ void RCTEnableTurboModuleSyncVoidMethods(BOOL enabled)
gTurboModuleEnableSyncVoidMethods = enabled;
}

static BOOL gBridgeModuleDisableBatchDidComplete = NO;
BOOL RCTBridgeModuleBatchDidCompleteDisabled(void)
{
return gBridgeModuleDisableBatchDidComplete;
}

void RCTDisableBridgeModuleBatchDidComplete(BOOL disabled)
{
gBridgeModuleDisableBatchDidComplete = disabled;
}

BOOL kDispatchAccessibilityManagerInitOntoMain = NO;
BOOL RCTUIManagerDispatchAccessibilityManagerInitOntoMain(void)
{
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/React/Base/RCTBridgeModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ RCT_EXTERN_C_END
/**
* Notifies the module that a batch of JS method invocations has just completed.
*/
- (void)batchDidComplete;
- (void)batchDidComplete RCT_DEPRECATED;

/**
* Notifies the module that the active batch of JS method invocations has been
Expand Down
24 changes: 18 additions & 6 deletions packages/react-native/React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1531,15 +1531,27 @@ - (void)partialBatchDidFlush

- (void)batchDidComplete
{
// TODO #12592471: batchDidComplete is only used by RCTUIManager,
// can we eliminate this special case?
for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.implementsBatchDidComplete) {
if (RCTBridgeModuleBatchDidCompleteDisabled()) {
id uiManager = [self moduleForName:@"UIManager"];
if ([uiManager respondsToSelector:@selector(batchDidComplete)] &&
[uiManager respondsToSelector:@selector(methodQueue)]) {
[self
dispatchBlock:^{
[moduleData.instance batchDidComplete];
[uiManager batchDidComplete];
}
queue:moduleData.methodQueue];
queue:[uiManager methodQueue]];
}
} else {
// TODO #12592471: batchDidComplete is only used by RCTUIManager,
// can we eliminate this special case?
for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.implementsBatchDidComplete) {
[self
dispatchBlock:^{
[moduleData.instance batchDidComplete];
}
queue:moduleData.methodQueue];
}
}
}
}
Expand Down

0 comments on commit 55f0ffa

Please sign in to comment.