![](/img/trans.png)
[英]How to tell SwiftUI views to bind to more than one nested ObservableObject
[英]SwiftUI - ObservableObject redraws unrelated views?
当@Published
属性在ObservableObject
发生突变时,SwiftUI似乎会重新绘制不依赖于该属性的视图。
您可以在此处查看行为:
// Our observed model
class Person: ObservableObject {
@Published var name = "Bob"
@Published var title = "Mr"
static let shared = Person()
init() {}
}
// Name view
struct NameView: View {
@ObservedObject var person = Person.shared
var body: some View {
print("Redraw name")
return TextField("Name", text: $person.name) // Binding to `name` only
}
}
/* Elsewhere in the app... */
// Title view
struct TitleView: View {
@ObservedObject var person = Person.shared
var body: some View {
print("Redraw title")
return TextField("Title", text: $person.title) // Binding to `title` only
}
}
构建一个包含两个视图的应用,然后更改名称或标题。 对于每个键入的字符,您将看到以下控制台输出:
Redraw name
Redraw title
为什么在修改name
时会重新计算TitleView
的主体,反之亦然?
这在我的应用程序中已成为一个巨大的问题:共享的User
对象(通过@EnvironmentObject)正在触发完全不相关的视图中的绘制周期。 在一个视图中修改User
名会导致另一个视图重新渲染由同一User
拥有的一长串照片(昂贵的操作)。 更糟糕的是,每次键入击键都会发生这种情况。
SwiftUI是否足够聪明,可以有选择地重绘仅显示突变的@Published属性的视图?
在@ObservedObject
使用组合Subscriber
观察ObservableObject
。
考虑您的Person
对象的以下重构:
class Person: ObservableObject {
var name = "My name" {
willSet { self.objectWillChange.send() }
}
var title = "My title" {
willSet { self.objectWillChange.send() }
}
static let shared = Person()
init() {}
}
如您所见, Person
对象“拥有”一个分配给objectWillChange
的Publisher
objectWillChange
。 @Property
所做的只是通过为您处理willSet
从对象模型中删除一些样板。
因此, ObservableObject
本身的粒度不足以检测模型中特定属性的更改,而是“广播”模型中任何属性更改的更改,而@ObservedObject
只是订阅了模型中的任何更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.