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
  • 第二部分:MVVM 在 SwiftUI 中的实现

第二部分:MVVM 在 SwiftUI 中的实现

第5章:开发 ViewModel 层

数据绑定与 Combine 框架

核心概念

  1. Combine 框架简介

    • Apple 推出的响应式编程框架,用于处理异步事件和数据流
    • 基于 Publisher-Subscriber 模式,实现数据变化的自动传播
    • 与 SwiftUI 深度集成,是 MVVM 中数据绑定的理想解决方案
  2. 关键组件

    • @Published 属性包装器:标记需要观察的属性
    • ObservableObject 协议:使对象具备发布变化的能力
    • PassthroughSubject/CurrentValueSubject:手动控制的事件流

实现数据绑定

class TodoViewModel: ObservableObject {
    @Published var items: [TodoItem] = []
    
    private var cancellables = Set<AnyCancellable>()
    
    func fetchData() {
        NetworkService.fetchTodos()
            .sink(receiveCompletion: { _ in },
                  receiveValue: { [weak self] items in
                self?.items = items
            })
            .store(in: &cancellables)
    }
}

视图层绑定示例

struct TodoListView: View {
    @ObservedObject var viewModel: TodoViewModel
    
    var body: some View {
        List(viewModel.items) { item in
            Text(item.title)
        }
        .onAppear {
            viewModel.fetchData()
        }
    }
}

高级技巧

  1. 双向绑定

    • 使用 Binding 包装器实现视图与 ViewModel 的双向交互
    TextField("Title", text: $viewModel.newItemTitle)
    
  2. 数据流组合

    • 使用 Combine 操作符(map/filter/combineLatest)处理复杂逻辑
    $searchText
        .combineLatest($items)
        .map { text, items in
            text.isEmpty ? items : items.filter { $0.title.contains(text) }
        }
    
  3. 错误处理

    • 通过 catch 和 replaceError 处理网络请求异常

性能优化

  • 使用 debounce 处理高频事件(如搜索输入)
  • 避免在主线程执行耗时操作
  • 及时释放 AnyCancellable 防止内存泄漏

常见问题解决方案

  1. 绑定失效

    • 确保遵守 ObservableObject 协议
    • 检查 @Published 属性是否被正确标记
  2. 内存泄漏

    • 使用 [weak self] 捕获列表
    • 在适当时机调用 cancel()
  3. 线程冲突

    • 使用 receive(on:) 指定 UI 更新线程
    .receive(on: DispatchQueue.main)
    

最佳实践:将 Combine 逻辑封装到 ViewModel 的扩展中,保持主要业务逻辑的清晰性。

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