diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index c719b56289171e..8b0c4c192fa921 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -439,7 +439,8 @@ - (NSString *)textInputShouldChangeText:(NSString *)text inRange:(NSRange)range if (_onTextInput) { _onTextInput(@{ - @"text": text, + // We copy the string here because if it's a mutable string it may get released before we stop using it on a different thread, causing a crash. + @"text": [text copy], @"previousText": previousText, @"range": @{ @"start": @(range.location), diff --git a/React/CoreModules/RCTEventDispatcher.mm b/React/CoreModules/RCTEventDispatcher.mm index f2cf17c947eedf..3669e2e7d64b58 100644 --- a/React/CoreModules/RCTEventDispatcher.mm +++ b/React/CoreModules/RCTEventDispatcher.mm @@ -86,7 +86,9 @@ - (void)sendTextEventWithType:(RCTTextEventType)type }]; if (text) { - body[@"text"] = text; + // We copy the string here because if it's a mutable string it may get released before we dispatch the event on a + // different thread, causing a crash. + body[@"text"] = [text copy]; } if (key) { @@ -103,7 +105,9 @@ - (void)sendTextEventWithType:(RCTTextEventType)type break; } } - body[@"key"] = key; + // We copy the string here because if it's a mutable string it may get released before we dispatch the event on a + // different thread, causing a crash. + body[@"key"] = [key copy]; } RCTComponentEvent *event = [[RCTComponentEvent alloc] initWithName:events[type] viewTag:reactTag body:body];