在 SwiftUI 中,@State 属性包装器用于管理当前视图中的简单数据。当你想要在多个视图之间共享数据时,必须采取一些额外的步骤。
假设我们有一个 User
结构体来存储用户的名字和姓氏:
struct User {
var firstName = "Bilbo"
var lastName = "Baggins"
}
然后在 SwiftUI 视图中,我们使用 @State 属性包装器来创建一个 user
实例,并通过绑定($user.firstName
和 $user.lastName
)将这些数据与界面控件连接起来:
struct ContentView: View {
@State private var user = User()
var body: some View {
VStack {
Text("Your name is \(user.firstName)\(user.lastName).")
TextField("First name", text: $user.firstName)
TextField("Last name", text: $user.lastName)
}
}
}
user.firstName
或 user.lastName
发生变化时,视图就会重新渲染。在前面的代码中,我们使用了结构体 User
,这是一个值类型(值传递)。如果你将其改为类,则变成了引用类型(引用传递),并且行为发生了变化。
我们将 User
改为类后,问题就出现了:
struct User {
To this:
class User {
user
变成了一个类实例,数据发生改变时,类本身并没有被重新创建,@State 不会知道这个变化,从而导致视图不刷新。要解决这个问题,我们需要使用 @Observable 宏来告诉 SwiftUI,这个类是可观察的,并且当它的属性发生变化时,视图需要刷新。改成以下代码:
@Observable
class User {
User
类,只要其中的属性发生变化,视图也会正确地重新渲染。总之,使用 @Observable 可以让类成为可观察对象,从而保证当类内部数据发生变化时,SwiftUI 会重新渲染视图,避免了因为类的引用类型特性导致的视图不更新问题。