为什么 SwiftUI 用 “some View” 作为视图类型?
一、为什么 SwiftUI 用 “some View” 作为视图类型
SwiftUI 高度依赖 Swift 5.1 引入的一个强大特性,它叫 “opaque return types” ,它可以用于函数、方法和属性返回一些值,无需向调用API的客户端揭示该值的具体类型。每一次你看到 some View 的地方就是它了。它表示 “某个遵循View协议的特定类型,但我们不必说具体是什么”
返回 some View 相较只返回 View 有两个重要的区别:
我们必须总是返回相同的类型。尽管我们并不知道返回的 view 的类型,但编译器知道。名列前茅个区别对于性能至关重要:SwiftUI 需要能够监视我们正在展示的视图并理解它们如何变化,以便它能正确地更新用户接口。如果我们允许随机地改变视图(类型),对于 SwiftUI 来说,搞清楚究竟发生了什么变化会变得很慢 —— 基本上需要从头开始。
第个区别也很重要,因为 SwiftUI 用 ModifiedContent 构建起数据。之前我们向你展示过下面这份代码:
Button(“Hello World”) {
print(type(of: self.body))
}
.frame(width: 200, height: 200)
.background(Color.red)
这个代码创建了一个按钮,如果打印它的 Swift 类型,会给出一组由 ModifiedContent 构成的很长的输出。
View 协议有一个与之关联的类型。以 Swift 的方式,我们说 View本身没有任何含义—— 我们需要指出它精确的类型。就如果 Swift 不让我们说 “这个变量是个数组”,相反,它要求我们说数组里有什么:“这个变量是个字符串数组。”
因此,如下代码是不被允许的:
struct ContentView: View {
var body: View {
Text(“Hello World”)
}
}
但下面的代码则是完全合法的:
struct ContentView: View {
var body: Text {
Text(“Hello World”)
}
}
返回 View 没有意义,因为 Swift 希望知道视图里有什么 —— 它内心的空洞没被填满。另一方面,返回 Text 就是 OK 的,因为我们填补了这个空洞,Swift 知道视图是什么了。
现在我们回到早期的代码:
Button(“Hello World”) {
print(type(of: self.body))
}
.frame(width: 200, height: 200)
.background(Color.red)
如果我们想要在body 属性里返回上面任何一个视图类型,我们应该怎么书写代码?你可能会尝试搞清楚这些 ModifiedContent 泛型组合的结果,但这实际上太痛苦了,事实上我们根本不用关系,这些都是 SwiftUI 的活。
some View 说的是:“它将返回一个特定的 view 类型,比如Button 或者 Text,但我不想说具体是啥。” 因此,视图的空洞会被一个真实的视图填充,但不要求我们精确地写出这个冗长的类型。
延伸阅读:
二、SwiftUI生命周期
SwiftUI同UIKit和AppKit的主要区别之一是,SwiftUI的视图(View)是值类型,并不是对屏幕上绘制内容的具体引用。在SwiftUI中,开发者为视图创建描述,而并不实际渲染它们。
在UIKit(或AppKit)中,视图(或视图控制器)有明确的生命周期节点,比如vidwDidload、loadView、viewWillAppear、didAddSubView、didMoveToSuperview等方法,它们本质上充当了钩子的角色,让开发者能够通过执行一段逻辑来响应系统给定的事件。
SwiftUI的视图,本身没有清晰(可适当描述)的生命周期,它们是值、是声明。SwiftUI提供了几个修改器(modifier)来实现类似UIKit中钩子方法的行为。比如onAppear同viewWillAppear的表现很类似。同UIKit的钩子方法的位置有很大的不同, onAppear和onDisappear是在当前视图的父视图上声明的。
将UIKit视图包装成SwiftUI的视图时,我们需要了解两者生命周期之间的不同,不要强行试图找到完全对应的方法,要从SwiftUI的角度来思考如何调用UIKit视图。

猜你喜欢LIKE
相关推荐HOT
更多>>
Linux系统开机加电后发生了什么?
一、Linux系统开机加电后发生了什么电脑启动后,CPU逻辑电路被设计为只能运行内存中的程序,没有能力直接运行存在于软盘或硬盘中的操作系统,如...详情>>
2023-10-16 20:17:25
Medium Android客户端都使用了哪些开源项目?
1、RetrofitRetrofit是一个适用于 Android 和 Java 的类型安全的 HTTP 客户端,是一个针对Android平台的网络请求库,它基于OkHttp封装了网络请...详情>>
2023-10-16 19:21:33
MySql什么是数据库架构设计?
一、MySql什么是数据库架构设计MySQL是一种流行的关系型数据库管理系统,它被广泛用于Web应用程序和企业应用程序的开发。在MySQL中,数据库架构...详情>>
2023-10-16 13:21:22
JVM中的堆区为什么叫堆(heap),与数据结构中的堆是一个概念吗?
一、JVM中的堆区为什么叫堆(heap)JVM中的堆区和数据结构中的堆并不是一个概念。JVM中的堆区之所以叫做堆,是因为它的物理存储结构类似于堆(h...详情>>
2023-10-16 11:24:35热门推荐
OceanBase相比其他开源的noSQL数据库有什么优点?
沸Flash动画制作的原理是什么?
热为什么GIL让多线程变得如此鸡肋?
热为什么要用Lambda表达式?
新苹果电脑mac怎么安装SQL server?
C、C++、C#的区别?
Linux系统开机加电后发生了什么?
Python解释器,终端,编辑器区别和联系?
Medium Android客户端都使用了哪些开源项目?
MyBatis流行的原因?
transform和opacity动画为什么性能好?
JButton的e.getSource()和e.getActionCommand()方法有什么区别?
webpack中的url-loader和file-loader有哪些区别?
为什么 SwiftUI 用 “some View” 作为视图类型?
技术干货






