Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Ting
Ting

Posted on

     

SwiftUI与View Model:Apple的词语选择困难

前言

经过一段时间SwiftUI开发的朋友应该都注意到,Apple在其官方文档网站https://developer.apple.com/documentation/ 上刻意地避免使用“View Model”一词。

初学SwiftUI的开发者肯定会有疑问:为什么Apple不用众所周知的view model这个单词来描述处理数据逻辑的对象,而非得舍近求远地用各种近义词替换,什么Store啦、data model啦、或者指代事物的实体名词,来命名数据对象。这篇文章简单记录一下我的发现和猜测。

简史

经历过UIKit到SwiftUI转变的朋友们应该还记得,当SwiftUI随着iOS 13在2019年推出时,最开始其实是很粗糙、很不稳定的。在数据对象这一点上,SwiftUI第一版甚至没有@StateObject这个property wrapper。

最开始时大家对新技术也是一头雾水,很多手快的教程作者写的解读文章漏洞百出,我记忆中见过的误用包括……

  • 直接在view中用let声明数据对象的
  • @ObservedObject private var声明数据对象的
  • 用单例或者变种单例的Model.shared来保证数据对象唯一性的
  • @State这个在官方示例中只用来存储"plain old data"数值类型的property wrapper来声明class对象

过了大半年,大伙逐渐玩熟了SwiftUI以后,才明白过来,并不是我们写的代码有问题,而是SwiftUI 1.0根本就没办法“优雅”地声明一个唯一的observable object。记得无论是developer forum还是swift.org的forum,都有好几个帖子讨论这个问题。最终这个问题随着Apple在iOS 14引入@StateObject而得到彻底解决。

变迁

在iOS 13到15之间,Apple自己对于数据对象的理解也在不断演化。有个新来的只接触过现代SwiftUI的小同事问我,“为啥苹果文档里,有的地方管它叫XXStore,有的叫XXModel?”我自己的观察如下:

  • “Store”:示例文档 这个文档是iOS 14时代推出的。当时刚有的@StateObject,Apple自己还在纠结这些概念性的名词应该怎么称呼,所以并没有选择如今更为常见的“Model”来命名变量。
  • “Model”:示例文档 当进入iOS 15的时代,SwiftUI也开发到第三版,其整体架构和稳定性都上了一个台阶。这时候Apple的命名策略也稳定下来,大致为:若一个数据对象是真实世界中实际存在的物体,如一本书Book,或者参会者Attendee,则用实际名词命名;如果数据对象是抽象的,只为了处理一个view的所有数据逻辑,则将其命名为data model。这样就可以无所顾忌地把所有“有的没的”参数全都塞到一个对象里面 🤪
  • “view model”:示例文档 在几乎所有的Apple官方文档中,它们尽可能地避免使用view model这个词。百密一疏,还真让我撞见一个审稿疏忽的文档!可以看到,SwiftUI首页链接的数据模型概念文档里面“model”一词用了四十余次,“data model”十余次,可一次“view model”都没用。所以,我觉得Apple是故意避免使用view model这个词的。至于为什么,接着往下看……

我估摸着苹果内部开发是不在乎对象是否为ViewModel()创建。只是在对外的文档中统一口径,不用这个词罢了。你装你🐴呢

为何避免View Model?

对于这个问题最有代表性的讨论,是Apple Developer Forum上广为讨论的一个帖子:https://forums.developer.apple.com/forums/thread/699003

简单来说,很多人在写了很多SwiftUI代码后,发现刻意加入一个传统的MVVM模式中的view model是完全没必要的。传统的MVVM里view model主要用来处理数据和视图的双向绑定:数据进来,更新视图;视图状态变化,反馈给数据。直到2021年,我看到还有许多企业做demo时,宣传要合理地建模view model说的就是你MongoDB。但实际上,除了直接在客户端操作数据库的情况以外,如今很少有需要在用户逻辑层面大量操作数据的app了。

自从Apple引入@StateObject之后,SwiftUI的数据模型虽然性能一般,但变得容易理解。数据类型用state和binding和environment,引用类型用state object和observed object和environment object。很多情况下,通过合理的access level控制和正确的property wrapper使用,双向数据绑定只需要view和model两个层面即可。以往MVC中一团浆糊的controller,和MVVM中的view model,都被简化了。

我猜Apple的本意就在这儿:能简化的问题,没必要“为了设计模式而设计模式”。诚然,我们可以根据传统的MVVM模式,为每一个视图配一个view model和一个model,但那样就增加了许多不必要的胶水代码,需要测试的代码也成倍增加。Apple就想了,干脆我们不把数据模型叫view model,刻意地让读者明白新的MV模式不涉及到手动双向绑定,这样就能扭转大家的过时的思路。

Observable更进一步

在iOS 17里,Apple采纳了社区提出的Observation模式,把原先state object和observable object的模式进一步简化。我想它的本意是让开发者把数据模型更加细化,明确哪些属性会导致视图更新,哪些不会。而不要再犯“一万行controller”的错误。

SwiftUI走过五年时光,由于兼容性的考虑,很多走错的路,只好木已成舟、顺水推舟。如果重新再来、从头设计,或许很多关键概念的选词,会有更好、更直观的选择。

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Swift@Esri, ECE@Duke, Physics@BUPT
  • Location
    Redlands, CA
  • Education
    Duke
  • Pronouns
    He/Him
  • Work
    Sr Product Engineer at Esri
  • Joined

More fromTing

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp