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 d79f9029bb7..f4de8848613 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 @@ -171,10 +171,14 @@ - (void)dealloc - (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args { - if (_valid) { - _reactInstance->callFunctionOnModule( - [moduleName UTF8String], [method UTF8String], convertIdToFollyDynamic(args ? args : @[])); + // This is called from arbitrary threads, while -invalidate destroys _reactInstance on + // the JS thread, so checking _valid and dereferencing have to happen as one step. + std::lock_guard lock(_invalidationMutex); + if (!_valid || !_reactInstance) { + return; } + _reactInstance->callFunctionOnModule( + [moduleName UTF8String] ?: "", [method UTF8String] ?: "", convertIdToFollyDynamic(args ? args : @[])); } - (void)invalidate