6-3.【架构设计】MVVM 在SwiftUI中是否仍然成立?在SwiftUI里,View/ViewModel的边界和UIKit有什么本质差异?

1 阅读2分钟

一、SwiftUI 中 MVVM 是否仍然成立?

答案:成立,但方式不同

  • Model:和 UIKit 一样,负责业务状态和数据逻辑

  • ViewModel:仍然负责:

    • 数据转换(格式化、过滤、排序)
    • 用户交互处理(逻辑/状态更新)
  • View:只负责声明 UI 和绑定状态

但是 SwiftUI 里 MVVM 的实现机制和 UIKit 不同

  • SwiftUI 的 View 是值类型(struct) ,每次状态改变都会重新生成
  • State/Binding/ObservedObject/EnvironmentObject 替代了 UIKit 的手动更新和生命周期管理
  • ViewModel 通常通过 ObservableObject + @Published 来驱动 View 更新

二、View/ViewModel 边界的本质差异

维度UIKitSwiftUI说明
View 类型UIView / UIViewController(引用类型)struct View(值类型)SwiftUI 的 View 不持有状态,只是渲染和响应绑定
View 生命周期明确(viewDidLoad / viewWillAppear / viewDidAppear / viewWillDisappear / deinit)随状态重建(struct 被频繁创建)View 不再是逻辑存储点,不能放业务状态
状态存储ViewController 持有状态(容易膨胀)@State、@StateObject、@ObservedObject 持有状态使状态脱离 View 直接存于 ViewModel 或 SwiftUI 系统
绑定方式手动:通知 VC 更新 View(reloadData、setNeedsLayout)自动:声明式绑定($binding、@Published、Combine)数据流驱动 UI,无需手动刷新
生命周期依赖VC 生命周期是逻辑天然容器ViewModel 生命周期独立于 View(@StateObject 生命周期通常绑定 View 层次,但不依赖 View 构造)避免了 VC 式的“膨胀”问题

🔑 核心差异

  1. View 是轻量的值类型,不再承担状态

    • UIKit: View + VC = 状态 + 逻辑 + 展示
    • SwiftUI: View 只渲染,状态和逻辑放到 ViewModel
  2. 状态绑定自动驱动 UI

    • UIKit: 手动调用 reload/update
    • SwiftUI: @Published + @StateObject 自动刷新
  3. 生命周期解耦

    • UIKit: VC 生命周期就是状态容器生命周期 → 导致 Massive VC
    • SwiftUI: ViewModel 可以用 @StateObject 绑定 View 生命周期,也可以用 EnvironmentObject 跨 View 层共享 → 避免膨胀

三、SwiftUI MVVM 实践示意

// Model
struct User {
    let id: String
    let name: String
}

// ViewModel
class UserViewModel: ObservableObject {
    @Published var displayName: String = ""
    
    private var user: User
    
    init(user: User) {
        self.user = user
        self.displayName = "Name: (user.name)"
    }
}

// View
struct UserView: View {
    @StateObject var viewModel: UserViewModel
    
    var body: some View {
        Text(viewModel.displayName)
    }
}

特点:

  • View 只是声明 UI (Text)
  • ViewModel 持有 Model(或快照),负责逻辑
  • ViewModel 通过 @Published 自动驱动 View 更新
  • View 是 struct,每次状态变化可以安全重建

四、总结 SwiftUI MVVM 本质差异

  1. 轻量 View → 不存逻辑、不存状态
  2. 自动状态绑定 → 解除手动刷新压力
  3. ViewModel 生命周期解耦 → 避免 Massive ViewController 问题
  4. 声明式 UI → View 只是渲染函数,ViewModel 是“真正的逻辑容器”

可以说 SwiftUI 让 MVVM 回归“理论本意”:View 真正只管渲染,逻辑和状态完全在 ViewModel,不像 UIKit MVC/MVVM 那样天然会膨胀。