Avoid crashes when RCTInstance is ready but modules are loaded (#50499)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50499

We enocuntered an issue internally where the `RCTInstance` was ready before the modules were done registering statically.
When this happens, it can occur that we iterate over an array that is going to be modified.

With this change, we are introducing several changes:
- By default the logs are not outputted, so the array is not going to be populated
- we are making a copy of the array before we start iterating, so even if the original reference is updated, the iteration is safe
- we are not emitting logs if in release mode. This will protect production from this issue. Also, these warns are not going to be useful in production anyway.

## Changelog:
[Internal] - fix crash when RCTInstance is ready while modules are initialized

## Facebook:
This fixes T220205371

Reviewed By: Abbondanzo

Differential Revision: D72512518

fbshipit-source-id: 32e561111d034455a6a778d05af4a96602b74bfb
This commit is contained in:
Riccardo Cipolleschi
2025-04-06 02:23:30 -07:00
committed by Facebook GitHub Bot
parent f0ad394464
commit c0d96a5bc6
2 changed files with 8 additions and 4 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ BOOL RCTAreLegacyLogsEnabled(void)
dispatch_once(&onceToken, ^{
NSNumber *rctNewArchEnabled =
(NSNumber *)[[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTLegacyWarningsEnabled"];
_legacyWarningEnabled = rctNewArchEnabled == nil || rctNewArchEnabled.boolValue;
_legacyWarningEnabled = rctNewArchEnabled.boolValue;
});
return _legacyWarningEnabled;
}
@@ -517,14 +517,19 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
// Set up hot module reloading in Dev only.
[strongSelf->_performanceLogger markStopForTag:RCTPLScriptDownload];
[devSettings setupHMRClientWithBundleURL:sourceURL];
#if RCT_DEV
[strongSelf _logOldArchitectureWarnings];
#endif
}];
}
- (void)_logOldArchitectureWarnings
{
NSMutableArray<NSString *> *modulesInOldArchMode = getModulesLoadedWithOldArch();
if (!RCTAreLegacyLogsEnabled()) {
return;
}
NSArray<NSString *> *modulesInOldArchMode = [getModulesLoadedWithOldArch() copy];
if (modulesInOldArchMode.count > 0) {
NSMutableString *moduleList = [NSMutableString new];
for (NSString *moduleName in modulesInOldArchMode) {
@@ -533,7 +538,6 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
RCTLogWarn(
@"The following modules have been registered using a RCT_EXPORT_MODULE. That's a Legacy Architecture API. Please migrate to the new approach as described in the https://reactnative.dev/docs/next/turbo-native-modules-introduction#register-the-native-module-in-your-app website or open a PR in the library repository:\n%@",
moduleList);
[modulesInOldArchMode removeAllObjects];
}
}