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

SwiftUI中@Published修饰子类实例属性变更不触发视图更新如何解决

问题根本原因

@Published 对引用类型(class)只会监听指针地址的变化,不会监听引用对象内部的属性变更:
你代码中定义的 People、SuperMankind、Mankind 全是 class 类型,ViewModel 中 @Published 修饰的 mankind 属性只有在被整体赋值新的 Mankind 对象时,才会触发视图更新通知。你修改的是 mankind.people 数组,mankind 本身的内存地址没有发生变化,因此 @Published 不会推送变更事件,视图就不会刷新。
你手动调用 viewModel.objectWillChange.send() 有效的原因,就是主动触发了 ObservableObject 的全局变更通知,告知 SwiftUI 需要刷新关联视图。

可选修复方案

方案1:将数据模型改为值类型(优先选择)

如果没有必须使用 class 的业务需求(比如继承、共享引用状态),把所有数据模型改成 struct 即可自动解决问题:struct 是值类型,内部属性修改时整个值会发生变化,@Published 可以自动检测到变更。
修改后的参考代码:

// 无继承需求时改用struct,Identifiable可直接遵守
struct People: Identifiable {
    let id = UUID()
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

struct Men {
    var people: [People] = []
}

class ViewModel: ObservableObject {
    @Published var mankind = Men()
}

如果需要保留泛型逻辑也可以对应调整为 struct 实现。

方案2:数据类遵守ObservableObject

如果必须保留 class 继承逻辑,让你的数据类也遵守 ObservableObject,内部可变属性加 @Published 修饰:

class SuperMankind<PlayerType: People>: ObservableObject {
    @Published var people: [PlayerType] = []
}

可以在 ViewModel 中手动订阅数据类的变更事件,转发到 ViewModel 自身的变更通知:

import Combine

class ViewModel: ObservableObject {
    @Published var mankind: Mankind
    private var cancellable: AnyCancellable?
    
    init(_ m: Mankind) {
        mankind = m
        // 监听mankind的内部变更,转发到当前ViewModel的变更通知
        cancellable = mankind.objectWillChange.sink { [weak self] _ in
            self?.objectWillChange.send()
        }
    }
}

方案3:封装修改逻辑到ViewModel

不想改动现有数据层结构的话,把所有修改 mankind 内部属性的逻辑封装到 ViewModel 内部,修改完成后统一手动发送通知,避免在 View 层到处调用 send():

class ViewModel: ObservableObject {
    @Published var mankind: Mankind
    
    init(_ m: Mankind) {
        mankind = m
    }
    
    func addMen(name: String) {
        mankind.people.append(Men(name: name))
        objectWillChange.send()
    }
}

// View层按钮点击直接调用封装好的方法
Button("Add") {
    viewModel.addMen(name: Int.random(in: 0...1000).description)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:15:04