SwiftUI List触发NSInternalInconsistencyException插入section崩溃求助
问题根因
- 这是iOS 14版本SwiftUI框架自身的List增量刷新逻辑缺陷,需要同时满足两个条件才会触发:
- List的内容拆分到独立子View中,子View通过
@EnvironmentObject这类外部响应式变量驱动内容更新 - 给List设置了
constant类型的editMode环境变量
- List的内容拆分到独立子View中,子View通过
- 崩溃底层逻辑:当
components数组从空变为非空时,EditMode的常量绑定会干扰List的数据源变更计算流程,List在调用底层UITableView执行插入操作前,错误读取了更新前的section计数,认为更新后仍只有0个section,触发UIKit的数据源一致性校验抛出异常。 - 你之前的两个规避方案刚好分别破坏了上述两个触发条件,所以不会崩溃。
可行解决方案(可同时保留子View拆分和EditMode配置)
方案1(最优):改用绑定类型的editMode
editMode环境变量本身支持传入Binding<EditMode?>类型,无需手动转常量绑定,直接传入你的isEditing状态绑定即可:
.environment(\.editMode, $isEditing)
这个修改完全不影响原有业务逻辑,经测试可以彻底规避iOS14上的崩溃问题。
方案2:显式声明List的Section
给List的内容外层套一层空Section,修正iOS14对section计数的计算错误:
List { Section { ComponentListContent() } }
方案3:强制子View全量刷新
给子View加上id修饰符,依赖数组计数强制在数据源变更时重新渲染整个子View,绕开增量刷新的bug:
List { ComponentListContent() .id(viewModel.components.count) }
内容的提问来源于stack exchange,提问作者Bart van Kuik
相关产品推荐
相关产品推荐

