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

SwiftUI使用ObservableObject/@Published时点击按钮视图不更新

问题根因

这是SwiftUI ObservableObject 嵌套使用的经典问题,核心机制是:@Published 仅会在属性本身被重新赋值时,触发所属ObservableObject的更新通知,不会自动感知嵌套的、同样遵循ObservableObject的引用类型实例的内部属性变化。
你代码里的具体问题点:

  • MyData、User都是class引用类型,存储在DataBase的data、users数组里。当你调用db.data[0].array.append(...)时,修改的是数组下标指向的MyData实例内部属性,并没有给db.data属性本身重新赋值新数组,因此DataBase的objectWillChange事件根本不会触发,持有db的ShowView监听不到变化,自然不会刷新。
  • 你在List中遍历拿到的user、data实例,没有显式标记为@ObservedObject,哪怕这些实例自身的@Published属性触发了更新,当前视图也没有订阅对应事件,不会触发重绘。
  • 额外隐患:ContentView中直接用let db = DataBase(...)创建实例,当视图发生重绘时会重新生成全新的DataBase对象,导致状态丢失,正式代码需要用@StateObject标记持有。

你提到的DispatchQueue.main.async主线程调度写法本身没有问题,本次视图不更新和线程逻辑无关。

修复方案

根据你的业务场景二选一即可:

方案1:保留class引用类型,补全订阅逻辑

适合需要跨多个位置共享同一份数据实例引用的场景:

  1. 首先修正ContentView的实例持有方式,避免重复初始化:
struct ContentView: View {
    @StateObject var db = DataBase(data: data, users: users)
    
    var body: some View {
        ShowView(db: db)
    }
}
  1. 在List遍历子对象时,显式声明@ObservedObject订阅对应实例的更新:
List(db.users) { user in
    @ObservedObject var userItem = user
    Text("\(userItem.name) \(userItem.data.type)")
    Text("\(userItem.data.array.count)")
    Divider()
}

List(db.data) { dataItem in
    @ObservedObject var dataEntry = dataItem
    Text("\(dataEntry.type)")
    Text("\(dataEntry.array.count)")
    Divider()
}

方案2:改用struct值类型,适配SwiftUI原生状态机制

如果不需要跨场景共享数据引用,这是更推荐的写法:把MyData、User从class改成struct,移除多余的ObservableObject遵循。
struct是值类型,当你修改它的内部属性时,等价于给数组对应位置重新赋值了新的实例,会自动触发外层@Published的更新通知,完全不需要处理嵌套订阅逻辑:

struct MyData: Identifiable {
    let id = UUID()
    var type: String
    var array: [Double]
    
    init(type: String, array: [Double]) {
        self.type = type
        self.array = array
    }
}

struct User: Identifiable {
    var id: UUID = UUID()
    var name: String
    var data: MyData
    
    init(name: String, data: MyData) {
        self.name = name
        self.data = data
    }
}

改完之后不需要修改视图里的其他逻辑,点击按钮就能正常触发视图更新。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:46:03