本文转载自微信公众号「Swift社区」,作者韦弦Zhy 。转载本文请联系Swift社区公众号。
如果您曾经为 UIKit 或 AppKit(Apple 的 iOS 和 macOS 原始用户界面框架)编程,您会知道它们使用类而非结构体来构造视图。SwiftUI 并非如此:我们更喜欢将结构体用于整体视图,这有两个原因。
首先,有一个性能因素:结构体比类更简单,更快。我之所以说性能因素,是因为很多人认为这是 SwiftUI 使用结构体的主要原因,而实际上这只是更大范围的一部分。
在 UIKit 中,每个视图都来自一个名为UIView的类,该类具有许多属性和方法:背景色,确定其放置方式的约束,用于将其内容呈现到其中的图层等等。其中有很多,每个UIView和UIView子类都必须具有它们,因为继承是这样工作的。
struct or class
通常这不是问题,但是有一个名为 UIStackView 的特定子类,它类似于 SwiftUI 中的 VStack 和 HStack。在 UIKit 中,UIStackView 是一种非渲染视图类型,旨在简化布局,但这意味着即使它因为继承的原因具有背景色,也从未真正使用过。
在 SwiftUI 中,我们所有的视图都是简单的结构体,几乎可以自由创建。想想看:如果您制作一个仅包含一个整数的结构体,则结构体的整个大小就是:一个整数。没有其他的。没有从父类,祖父母类或曾祖父母类等继承的多余值——它们完全包含您可以看到的内容,仅此而已。
得益于现代 iPhone 的强大功能,我不会慎重考虑后创建 1000 个整数甚至 100,000 个整数——眨眼之间就会发生。1000 个 SwiftUI 视图甚至 100,000 个 SwiftUI 视图也是如此。他们是如此之快,以至于不再值得考虑。
但是,尽管性能很重要,但视图作为结构体还是有很多更重要的事情:它迫使我们考虑以一种干净的方式隔离状态。您会发现,类能够自由更改其值,这可能导致代码混乱—— SwiftUI 如何知道什么更改了值并需要更新 UI?
通过生成不会随时间变化的视图,SwiftUI 鼓励我们转向更具功能性的设计方法:在将数据转换为 UI 时,我们的视图变成简单的,惰性的东西,而不是会失去控制的智能化的东西。
当您查看可以作为视图的事物时,可以看到这一点。我们已经使用了 Color.red 和 LinearGradient 作为视图——包含很少数据的简单类型。实际上,您不能找到比使用 Color.red 作为视图的更好的主意:除了“用红色填充我的空间”之外,它不包含任何信息。
相比之下,Apple 的UIView文档[1]列出了 UIView 拥有的约200种属性和方法,无论是否需要它们,所有这些属性和方法都将传递给其子类。
**提示:**如果您在视图中使用类,则可能会发现代码无法编译或在运行时崩溃。
参考资料
[1]UIView文档: https://developer.apple.com/documentation/uikit/uiview