第二部分: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. 实战技巧
避免直接修改状态:
// 错误做法(违反单向数据流) Button("Update") { viewModel.tasks[0].isCompleted.toggle() // 直接修改 published 属性 } // 正确做法 Button("Update") { viewModel.toggleTaskCompletion(id: task.id) // 通过 ViewModel 方法处理 }复杂事件处理示例:
// 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 各层级的职责清晰。
