From c0d96a5bc63ca4e1c1bf4d9a3753dd8d96d7d433 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Sun, 6 Apr 2025 02:23:30 -0700 Subject: [PATCH] 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 --- packages/react-native/React/Base/RCTUtils.mm | 2 +- .../runtime/platform/ios/ReactCommon/RCTInstance.mm | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/react-native/React/Base/RCTUtils.mm b/packages/react-native/React/Base/RCTUtils.mm index d1ac5cefae3..7d7eba0e55f 100644 --- a/packages/react-native/React/Base/RCTUtils.mm +++ b/packages/react-native/React/Base/RCTUtils.mm @@ -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; } diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm index bf07abd5a02..df8e878ae26 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm @@ -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 *modulesInOldArchMode = getModulesLoadedWithOldArch(); + if (!RCTAreLegacyLogsEnabled()) { + return; + } + + NSArray *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]; } }