SwiftUI 与 UIKit 的不同

转自: https://zhuanlan.zhihu.com/p/102707163

如果你曾经搞过 UIKit 或者 AppKit 的开发 (这两个框架是 Apple 为 iOS 和 macOS 提供的原生 UI 框架),那你一定知道,它们用 class 来表示 view,而不是 struct。SwiftUI 不这么做 —— 理由如下。

首先,涉及一个性能原理:结构体比类更简单,更轻量。之所以第一个说这个原因,是因为大多数都认为这是 SwiftUI 采用结构体的主要原因。其实,纵观全局,这只是原因之一。

在 UIKit 中,所有的视图都继承自一个叫 UIView 的类,它有非常多的属性和方法 —— 背景颜色,布局约束,用于渲染的层,等等。还有更多诸如此类的属性,而每一个 UIViewUIView 的子类都有,因为这正是继承的工作方式。

通常这样也不会带来问题,但有一个特殊的子类叫 UIStackView,它和 SwiftUI 里的 VStackHStack 相似。在 UIKit 里,出于使布局更简单的设计意图,UIStackView 是一个不会被渲染的视图类型。但由于继承机制,尽管它不渲染,它也有那些包括背景颜色在内的各种用不上的属性。

在 SwiftUI 中,所有的视图都是细碎的结构体,创建开销几乎可以忽略。 想象一下:你创建了一个结构体,持有一个整数,整个结构体的大小只有——那个整数,再无其他。没有从父类、爷爷类、爷爷的爷爷类那里继承来的“意外财产”。它所包含的一切你都看得见。

得益于现代 iPhone 的能力,创建 1000 甚至 100,000 个整数只在眨眼之间。对于 SwiftUI 的 1000 个 view 或者 100,000 个 view。这个时间仍然成立。太快了,你都不必考虑它们。

不过,除了性能,用 struct 表示 view 还有其他重要原因:它强迫我们以一种更干净的方式隔离状态。类可以自由地修改它的值 —— 这可能导致更凌乱的代码,这样的话 SwiftUI 就无法通过某个值的变化来自动更新 UI 了。

通过创建不会跟随时间改变的视图,SwiftUI 鼓励我们迁移到一种可以更好地工作的设计方式:视图变简单,变“蠢”,它只做把数据变成 UI 的事情,而不是滋生出控制逻辑这样更“智能”的工作。

当你审视什么样的东西在 SwiftUI 中可以作为一个 view 的时候,你就会发现前面说的方式正在运作。我们用 Color.redLinearGradient 作为视图 —— 一些存储非常简单数据的细碎类型。实际上,相对于把 Color.red 直接当成 view,你找不到更好的方案了。除了“把我的空间填满红色”,它没有携带其他任何多余的信息。

作为比较,你可以看下 Apple 的 UIView 文档 。上面列出了 200 多个UIView的属性和方法 —— 不管子类需不需要,都拿着。

提示: 如果你试图给你的 view 用上 class,那么代码要么编译不过要么就会崩溃。不要犹豫:用 struct 。

你可能感兴趣的:(SwiftUI 与 UIKit 的不同)