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 中的实现

第6章:MVVM 的数据流

跨层通信与事件处理

在 MVVM 架构中,跨层通信和事件处理是确保数据流清晰、逻辑解耦的关键环节。本节将探讨如何在 SwiftUI 中实现高效的跨层通信,并处理用户交互事件。

1. 跨层通信机制

MVVM 的层级间通信主要通过以下方式实现:

  • View → ViewModel:通过方法调用或属性绑定(如 @Binding)传递用户输入
  • ViewModel → View:通过 @Published 属性或 Combine 的 Publisher 驱动 UI 更新
  • ViewModel ↔ Model:直接调用模型方法或观察模型变化
// 示例:View 调用 ViewModel 方法
Button("Add Task") {
    viewModel.addTask(title: "New Task")
}

// ViewModel 内部处理
class TaskViewModel: ObservableObject {
    @Published var tasks: [Task] = []
    
    func addTask(title: String) {
        let newTask = Model.createTask(title: title) // 调用 Model 层
        tasks.append(newTask)
    }
}

2. 事件处理模式

SwiftUI 中常见的事件处理方式:

模式适用场景示例
闭包回调简单用户交互Button(action: { ... })
Combine 事件流复杂事件序列处理$searchText.debounce().sink()
NotificationCenter全局事件通知NotificationCenter.default.publisher
EnvironmentObject深层组件树事件传递@EnvironmentObject var router: AppRouter

3. 实战技巧

  1. 避免直接修改状态:

    // 错误做法(违反单向数据流)
    Button("Update") {
        viewModel.tasks[0].isCompleted.toggle() // 直接修改 published 属性
    }
    
    // 正确做法
    Button("Update") {
        viewModel.toggleTaskCompletion(id: task.id) // 通过 ViewModel 方法处理
    }
    
  2. 复杂事件处理示例:

    // ViewModel 中处理表单提交
    func submitForm() {
        guard validateInputs() else {
            errorMessage = "Invalid inputs"
            return
        }
        
        isLoading = true
        apiService.submit(formData)
            .receive(on: DispatchQueue.main)
            .sink { [weak self] completion in
                self?.isLoading = false
                // 处理错误...
            } receiveValue: { [weak self] response in
                self?.handleResponse(response)
            }
            .store(in: &cancellables)
    }
    

4. 常见问题解决方案

  • 循环引用:使用 [weak self] 避免内存泄漏
  • 线程安全:确保 UI 更新在主线程(DispatchQueue.main)
  • 过度更新:使用 objectWillChange.send() 手动控制发布时机

5. 案例:Todo 应用的事件流

// 完整事件流示例
struct TodoListView: View {
    @StateObject var viewModel = TodoViewModel()
    
    var body: some View {
        List {
            ForEach(viewModel.tasks) { task in
                TaskRow(
                    task: task,
                    onToggle: { viewModel.toggleTask(id: task.id) },
                    onDelete: { viewModel.deleteTask(id: task.id) }
                )
            }
        }
        .alert("Error", isPresented: $viewModel.showError) {
            Button("OK", role: .cancel) { }
        }
    }
}

通过合理设计跨层通信机制,可以构建出响应迅速、易于维护的 SwiftUI 应用,同时保持 MVVM 各层级的职责清晰。

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