Observation|创建 ViewModel 实例的最佳实践

了解如何在 SwiftUI 中管理 ViewModel 实例,适配 Observation 框架与新架构变更。

Observation|创建 ViewModel 实例的最佳实践

Combine(iOS 16 及以前)

在 Combine 框架中,通常使用 @StateObject 在 View 中创建 ViewModel 实例。

ViewModel 实例的生命周期:

  • @State 跟随 View
  • @StateObject 独立管理,View 重建时保持

以上,是很好的实践方案。

Observation(iOS 17 及以后)

但在 Observation 框架中,不再能使用 @StateObject,苹果建议使用基本的 @State

@State 的问题

如果在 View 组件中,直接使用使用 @State 创建 ViewModel 实例,很会导致 ViewModel 实例在预期之外的重复创建与销毁。

实际情况很复杂,并不是每次 View 更新都会导致 ViewModel 重建。例如如果有多个 View 使用同一个 ViewModel(例如 SummaryView 和 DetailView),就会导致同时存在多个 ViewModel 实例。还有其他一些情况,我也尚未完全弄明白。

但总的来说,使用 @State 确实会导致 ViewModel 实例难以管理的问题。因此,我需要尝试不同的方案来使用 ViewModel。

方案一 在 App 初始化并注入环境(苹果推荐)

这种方式是 Apple 推荐的方式,保留了优秀的可测试性。并且在 WWDC 实例项目中,也是这样做。

但就像我在下面这篇文章中所探讨的,这种用法在实际项目中会带来一些问题,例如:

  • 难以在 View 组件之外访问实例
  • 可能导致 App 文件中创建过多实例,导致管理困难。

方案二 使用单例模式

修改为使用单例之后,没有再出现重复实例的问题:

使用 Protocols 统一接口

用 Protocols 来统一 ViewModel 的接口设计,是 Apple 推荐的做法。

使用 Protocol 提供默认防抖功能

[ ] 待补充