SwiftData绑定导致聚焦形状时关闭应用崩溃问题求助
SwiftData绑定与可聚焦元素共存时关闭应用崩溃问题解决
问题描述
当SwiftUI控件(如Slider)绑定SwiftData模型的属性(如Double类型),且视图中存在独立的可聚焦形状(如Circle)时,若关闭应用时Circle处于聚焦状态,应用会触发崩溃,报错信息为:
SwiftData/BackingData.swift:124: Fatal error: Unable to get value - no backing Managed Object
复现条件
- 基于
DocumentGroup封装的文档型应用(测试环境:macOS 14.4.1) - 点击
Circle使其获得焦点后关闭文档,即可触发崩溃 - 若将焦点转移至
TextField等输入控件,关闭时不会崩溃,说明崩溃与Circle的聚焦状态直接相关
复现代码
import SwiftUI import SwiftData @Model class MyModel { init() {} var aValue: Double = 1.0 } @MainActor struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var myModels:[MyModel] var body: some View { HStack { ForEach(myModels) { model in Slider(value: Bindable(model).aValue, in: 0...1) Circle().focusable() } }.onAppear(){ if self.myModels.count == 0 { let model = MyModel() modelContext.insert(model) try? modelContext.save() } } } }
问题分析
崩溃根源在于:文档关闭时SwiftData托管对象已被销毁,但处于聚焦状态的Circle会干扰视图生命周期的回调顺序,导致Slider的绑定在对象销毁后仍尝试访问其属性——尽管Slider和Circle在视图结构上无直接关联,焦点状态却会影响绑定的释放时机。
解决方案
方法1:视图消失前主动清除焦点
通过@FocusState跟踪焦点状态,在视图即将消失时手动重置,避免聚焦元素干扰绑定释放:
@MainActor struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var myModels:[MyModel] @FocusState private var focusedCircleID: UUID? // 标记聚焦的Circle var body: some View { HStack { ForEach(myModels) { model in Slider(value: Bindable(model).aValue, in: 0...1) Circle() .focusable() .focused($focusedCircleID, equals: model.id) // 绑定焦点状态 } } .onAppear(){ if myModels.isEmpty { let model = MyModel() modelContext.insert(model) try? modelContext.save() } } .onDisappear { focusedCircleID = nil // 视图消失前清空焦点 } } }
方法2:拆分视图封装绑定与焦点状态
将每行的绑定和焦点状态封装到子视图中,让状态管理更独立,确保视图销毁时绑定与焦点同步释放:
@MainActor struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var myModels:[MyModel] var body: some View { HStack { ForEach(myModels) { model in ModelRowView(model: model) } } .onAppear(){ if myModels.isEmpty { let model = MyModel() modelContext.insert(model) try? modelContext.save() } } } } // 子视图封装绑定与焦点状态 struct ModelRowView: View { @Bindable var model: MyModel @FocusState private var isCircleFocused: Bool var body: some View { HStack { Slider(value: $model.aValue, in: 0...1) Circle() .focusable() .focused($isCircleFocused) } .onDisappear { isCircleFocused = false // 子视图消失时清除焦点 } } }
内容的提问来源于stack exchange,提问作者Richard Williamson
相关产品推荐
相关产品推荐

