Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 使用 @Published 和 ObservableObject

使用 @Published 和 ObservableObject

核心概念

ObservableObject 协议

  • 定义:ObservableObject 是 Combine 框架中的协议,用于标记类对象为可观察对象
  • 特点:
    • 必须继承自 AnyObject(即必须是 class 类型)
    • 自动合成 objectWillChange 发布者
    • 适用于管理应用状态和业务逻辑

@Published 属性包装器

  • 作用:自动为属性创建发布者,当属性值改变时通知订阅者
  • 特性:
    • 只能用于 ObservableObject 内部的属性
    • 隐式调用 objectWillChange.send()
    • 支持值类型和引用类型数据

实现机制

基本使用模式

class UserViewModel: ObservableObject {
    @Published var username: String = ""
    @Published var isLoggedIn: Bool = false
}

数据绑定原理

  1. 当 @Published 属性变化时触发更新
  2. SwiftUI 视图通过 @ObservedObject 或 @StateObject 监听变化
  3. 系统自动比较视图的依赖项决定是否需要重绘

实际应用

与视图的绑定方式

struct ProfileView: View {
    @ObservedObject var viewModel: UserViewModel
    
    var body: some View {
        TextField("Username", text: $viewModel.username)
        Toggle("Logged In", isOn: $viewModel.isLoggedIn)
    }
}

生命周期管理

属性包装器适用场景生命周期
@ObservedObject外部传入的 ViewModel跟随父视图更新
@StateObject视图自己创建的 ViewModel与视图生命周期一致

高级技巧

手动触发更新

class DataLoader: ObservableObject {
    var items: [String] = [] {
        willSet { objectWillChange.send() }
    }
    
    func loadData() {
        // 非@Published属性需要手动通知
        items = fetchData()
    }
}

性能优化建议

  1. 避免在 ViewModel 中过度使用 @Published
  2. 对复杂数据结构考虑使用 @Published private(set)
  3. 将相关属性分组到嵌套的 ObservableObject 中

常见问题解决方案

更新不触发的问题排查

  1. 检查类是否遵循 ObservableObject
  2. 确认视图使用了正确的属性包装器
  3. 验证是否在主线程更新属性

循环引用预防

class SafeViewModel: ObservableObject {
    @Published var data: [Item] = []
    
    // 使用弱引用打破循环
    weak var delegate: SomeDelegate?
    
    // 或者使用非持有引用
    var onUpdate: (() -> Void)?
}

最佳实践提示:对于简单的状态管理,优先考虑 @State 和 @Binding;当涉及复杂业务逻辑时再使用 ObservableObject 和 @Published 的组合。

Last Updated:: 4/25/25, 8:13 PM