英文:
SwiftUI 5: @Observable object updates using no property wrappers, State and Bindable
问题
我有以下使用XCode 15 beta 4的SwiftUI 5代码片段:
struct ContentView: View {
var person: Person = .init(id: UUID(), name: "Stacey")
//使用@State、@Bindable或在'person'之前不加任何修饰符都能完成相同的任务
var body: some View {
VStack {
Button {
person.name = "Sarah"
} label: {
Text("change name")
}
Text("Name: \(person.name)")
}
}
}
@Observable
class Person: Identifiable {
var id: UUID
var name: String
init(id: UUID, name: String) {
self.id = id
self.name = name
}
}
我想知道在ContentView中在Person变量之前使用@Bindable、@State或不使用修饰符的区别,因为使用这三种选择之一,person对象都可以成功更新,并且视图可以监听到新的更改。
英文:
I have the following SwiftUI 5 code snippet using XCode 15 beta 4:
struct ContentView: View {
var person: Person = .init(id: UUID(), name: "Stacey")
//using @State or @Bindable or nothing before 'person' does the same job
var body: some View {
VStack {
Button {
person.name = "Sarah"
} label: {
Text("change name")
}
Text("Name: \(person.name)")
}
}
}
@Observable
class Person: Identifiable {
var id: UUID
var name: String
init(id: UUID, name: String) {
self.id = id
self.name = name
}
}
I wonder what is the difference between using: @Bindable, @State, or nothing before the Person variable in the ContentView, because the person object updates successfully using any of those 3 choices, and the view can listen to the new change.
答案1
得分: 2
使用@Observable,您现在可以在体验中随处看到变化。
@Bindable用于进行更改,您可以使用$someObject.someProperty并更改对象的属性。
@State是真相之源,用于本地属性。
英文:
With @Observable you can now see changes everywhere as you are experiencing.
@Bindable is to make changes , you can use $someObject.someProperty and change the property of the object.
@State is a source of truth it is for local properties.
答案2
得分: 0
这是因为您在类声明之前应用了@Observable,将您的类Person标记为ObservableObject。因此,您的实例person将始终观察更新,无论您在视图中提供的任何附加注释如何。
通常,当您想要跟踪非自定义类的变量(如布尔值、字符串、整数等)的次要更改时,您会使用@State。@Bindable可以以类似的方式使用@State,只是更适用于将其应用于主视图中的自定义视图的初始化程序。请参考以下示例。
struct PrimaryView: View {
@State var updateCustomView: Bool = false
var body: some View {
CustomView(shouldUpdate: $updateCustomView)
}
}
struct CustomView: View {
@Bindable var shouldUpdate: Bool
var body: some View {
if shouldUpdate {
// 做一些操作
}
}
}
英文:
> //using @State or @Bindable or nothing before 'person' does the same job
This is because you marked your class Person as an ObservableObject via applying @Observable before the class declaration. Because of this, your instance, person will always observe updates regardless of any additional annotation you provide it in your view.
You typically use @State when you want to track minor changes to a variable of a non-custom class (like a boolean, string, integer, etc). @Bindable can be used in a similar fashion to @State except it is more useful to apply it to the initializer of a custom view within your primary view. See the following example.
struct PrimaryView: View {
@State var updateCustomView: Bool = false
var body: some View {
CustomView(shouldUpdate: $updateCustomView)
}
}
struct CustomView: View {
@Bindable var shouldUpdate: Bool
var body: some View {
if shouldUpdate {
// do stuff
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论