[iOS][Fabric] `RCTSwitchComponentView onChange:` dereferences `_eventEmitter` without a null check (EXC_BAD_ACCESS after view recycle)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 76/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- objective-c, react-native
- 领域
- mobile
调研方向
阅读 React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm,尤其是 onChange: 以及 issue 中提到的附近回收处理。比较报告中提到的同类组件视图里的 event emitter 防护,然后检查相关的 Switch 测试;如果现有测试表明存在这条路径,则为回收后的视图补充测试覆盖。完成标准是 onChange: 能安全处理已清空的 emitter,并且现有 Switch 行为仍有测试覆盖。
由索引模型根据 Issue 内容生成。
描述
Environment
- react-native 0.88.0 (first seen on 0.86.0; the file is byte-identical in both), New Architecture
- iOS 26.5.2 device (production crash), same code path on iOS 27
- Expo SDK 58 (not involved)
Description
-[RCTSwitchComponentView onChange:] (React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm:105-114) ends with
static_cast<const SwitchEventEmitter &>(*_eventEmitter) // line 113
.onChange(SwitchEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
with no check that _eventEmitter is set. RCTViewComponentView -prepareForRecycle resets it (RCTViewComponentView.mm:779, _eventEmitter.reset();), while _props stays valid, so the earlier *_props dereference does not fail.
Production crash (0.86.0, line 114 of that version), iOS 26.5.2:
EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS at 0x0000000000000030
0 React std::weak_ptr<EventDispatcher const>::lock()
1 React EventEmitter::dispatchEvent(...)
4 React SwitchEventEmitter::onChange(...)
5 React -[RCTSwitchComponentView onChange:]
6 UIKitCore -[UIApplication sendAction:to:from:forEvent:]
9 UIKitCore -[UISwitchModernVisualElement sendStateChangeActions]
11 UIKitCore -[UISwitchModernVisualElement _handleLongPressWithGestureLocationInBounds:...]
12 UIKitCore -[_UIAfterCACommitBlock run]
0x30 is a null this plus the eventDispatcher_ offset in EventEmitter.
Reproduction
Intermittent, not reproduced on demand. Conditions: iOS 26+, where the redesigned UISwitch (UISwitchModernVisualElement) delivers the state-change action from a deferred _UIAfterCACommitBlock instead of synchronously on touch-up (seen when the switch is dragged or long-pressed rather than tapped). If React re-renders and recycles the Switch view between the gesture ending and that block running, prepareForRecycle has already cleared _eventEmitter and onChange: runs on the recycled view.
Root cause
Missing null guard. Sibling components in the same directory tree already have it: RCTScrollViewComponentView, RCTImageComponentView, RCTModalHostViewComponentView, RCTVirtualViewComponentView (if (!_eventEmitter) { return; }), and RCTTextInputComponentView tests _eventEmitter before use at several sites. Switch is the outlier.
Proposed fix
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm
@@ -110,6 +110,9 @@ - (void)onChange:(UISwitch *)sender
return;
}
+ if (!_eventEmitter) {
+ return;
+ }
static_cast<const SwitchEventEmitter &>(*_eventEmitter)
.onChange(SwitchEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
}
We carry this as a local patch. Dropping the event is the right behaviour: the view has been recycled and no longer represents that React node.
Disclosure: drafted with AI assistance (Claude) from a patch we carry locally; code references were checked against the published package sources. Happy to clarify or open a PR.
- 主要语言
- C++
- 星标
- 127k
- 派生
- 25.3k
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
react/react-native 的其他 Issue
-
Linking.getInitialURL() returns the task's first link after a link relaunches a reclaimed Android app可能已有人在做 @YevheniiKotyrlo 于 7 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
react/react-native#59006 · 2 条评论 ·
维护者通常 1 天内回复
-
Fabric TextInput: prepareForRecycle leaves stale inputAccessoryViewButtonLabel (empty Done bar)可能已有人在做 @jkasprzyk17 于 7 天前认领。 未关闭Needs: Author Feedback Needs: Repro
难度 2/5 1-3 小时 新手友好度 76/100
react/react-native#58952 · 1 条评论 ·
维护者通常 1 天内回复
-
[iOS][Fabric] TextInput drops a keystroke right after the first character typed into an empty field (_textOf:equals: compares attributes of a focused field)可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭Needs: Attention Needs: Repro
难度 2/5 1-3 小时 新手友好度 78/100
react/react-native#58904 · 3 条评论 ·
维护者通常 1 天内回复
-
Needs: Author Feedback Needs: Repro
难度 2/5 1-3 小时 新手友好度 75/100
react/react-native#58659 · 2 条评论 ·
维护者通常 1 天内回复
-
Needs: Author Feedback Needs: Repro
难度 1/5 1 小时以内 新手友好度 92/100
react/react-native#58621 · 1 条评论 ·
维护者通常 1 天内回复
查看 react/react-native 的全部 Issue
相似的 Issue
-
cudf-polars feature request
难度 2/5 1-3 小时 新手友好度 77/100
维护者通常 2 天内回复
-
(S1 - Need confirmation)
难度 2/5 1-3 小时 新手友好度 68/100
CleverRaven/Cataclysm-DDA#89212 ·
维护者通常 1 天内回复
-
Status: Needs confirmation Status: Needs triage
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
a byte order mark at the start of a migration makes dbmate miss the up block可能已有人在做 @Dem1241 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 2 天内回复
-
ai_p2 comp-dictionary
难度 2/5 1-3 小时 新手友好度 78/100
ClickHouse/ClickHouse#127261 ·
维护者通常 1 天内回复