Swift 这个快捷界面如何绑定+;状态示例是否能够在不重新调用主体的情况下工作?
一位同事提出了下面的SwiftUI示例,它看起来就像预期的那样工作(您可以输入一些文本,它会在下面镜像),但它的工作方式令我惊讶Swift 这个快捷界面如何绑定+;状态示例是否能够在不重新调用主体的情况下工作?,swift,swiftui,Swift,Swiftui,一位同事提出了下面的SwiftUI示例,它看起来就像预期的那样工作(您可以输入一些文本,它会在下面镜像),但它的工作方式令我惊讶 import SwiftUI struct ContentView: View { @State var text = "" var body: some View { VStack { TextField("Change the string", text: $text
import SwiftUI
struct ContentView: View {
@State var text = ""
var body: some View {
VStack {
TextField("Change the string", text: $text)
WrappedText(text: $text)
}
}
}
struct WrappedText: View {
@Binding var text: String
var body: some View {
Text(text)
}
}
我的新手SwiftUI心智模型让我想到,在TextField中键入会改变$text
绑定,这反过来会变异text
@State变量。这将使ContentView
无效,触发对body
的新调用。但有趣的是,事实并非如此!在ContentView的body
中设置断点只会命中一次,而WrappedText的body
会在每次绑定更改时运行。然而,据我所知,文本
状态确实在变化
那么,这是怎么回事?为什么SwiftUI不在每次更改
文本时重新调用ContentView的主体?在状态更改时SwiftUI呈现引擎首先检查主体内的视图是否相等,如果其中一些视图不相等,则调用主体重新生成,但只调用那些不相等的视图。在您的情况下,没有一个视图(作为值)依赖于text
value(绑定就像一个引用-它是相同的),因此在这个级别上不需要重建任何内容。但是在WrappedText
内部,检测到带有新Text
的Text
与带有旧Text
的WrappedText
不相等,因此调用WrappedText
的主体来重新渲染此部分
这是对SwiftUI的渲染优化-通过平等性检查和验证准确的更改视图
默认情况下,该机制通过视图结构属性工作,但我们可以通过将视图确认为Eqatable
协议并将其标记为.equatable()
修饰符来参与该机制,以提供一些更复杂的逻辑来检测视图是否应该(或不应该)重新渲染