You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftData中@Model与@Published/ObservableObject共存及视图更新问题

问题解答

1. @Model与@Published/ObservableObject能否同时使用?

不能。@Model修饰的类,其属性会被SwiftData自动转换为计算属性(底层关联SwiftData的存储系统),而@Published无法应用在计算属性上,这就是你触发"Property wrapper cannot be applied to a computed property"错误的原因。

另外,@Model类本身已被SwiftData赋予可观察能力,完全不需要额外实现ObservableObject协议,SwiftData会自动跟踪属性变化并通知视图更新。

2. 解决视图不实时更新的方案

场景一:按钮修改score无实时反馈

你当前代码里的score是局部变量,修改它不会影响PracticeData实例的真实值,自然无法触发视图更新。正确做法是直接绑定PracticeData实例并修改其属性:

var body: some View {
    List {
        Section {
            ForEach(lesson.vocab) { vocab in
                // 用@Bindable包装实例,让SwiftData跟踪属性变化
                @Bindable var practiceData = vocab.practiceData
                
                HStack {
                    Text("\(practiceData.score)")
                    Button("addToScore") {
                        // 直接修改实例的score属性
                        practiceData.score += 1
                        // 如需立即持久化到存储,可添加:
                        // try? modelContext.save()
                    }
                }
            }
        }
    }
}

场景二:弹窗关闭后底层视图不更新

弹窗中修改results和latestResult时,要确保操作的是同一个SwiftData上下文里的PracticeData实例,让变化被视图感知:

  1. 在弹窗视图中用@Bindable包装传入的实例:
struct ResultSheetView: View {
    @Bindable var practiceData: PracticeData
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        Button("添加结果") {
            // 修改实例属性
            practiceData.results.append(PracticeResult(...))
            practiceData.latestResult = true
            dismiss()
        }
    }
}
  1. 弹出弹窗时直接传入目标实例:
// 底层视图触发弹窗的代码
Button("打开弹窗") {
    sheetPresented = true
}
.sheet(isPresented: $sheetPresented) {
    ResultSheetView(practiceData: vocab.practiceData)
}
  1. 确保底层视图的数据源(比如lesson.vocab)是通过SwiftData的@Query获取的,这样PracticeData变化时,@Query会自动刷新视图。如果是手动传递的静态数组,需改为从SwiftData查询获取。

内容的提问来源于stack exchange,提问作者trsommer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:35:22