[英]SwiftUI - ObservableObject redraws unrelated views?
When a @Published
property is mutated in an ObservableObject
, SwiftUI seems to re-draw views which do not depend on that property. 当
@Published
属性在ObservableObject
发生突变时,SwiftUI似乎会重新绘制不依赖于该属性的视图。
You can see the behavior here: 您可以在此处查看行为:
// 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
}
}
Build an app containing both views, and change either the name OR the title. 构建一个包含两个视图的应用,然后更改名称或标题。 For each character typed, you'll see this console output:
对于每个键入的字符,您将看到以下控制台输出:
Redraw name
Redraw title
Why does TitleView
's body get re-computed when you modify name
, and vice versa? 为什么在修改
name
时会重新计算TitleView
的主体,反之亦然?
This has become a huge problem in my app: a shared User
object (via @EnvironmentObject) is triggering drawing cycles in completely unrelated views. 这在我的应用程序中已成为一个巨大的问题:共享的
User
对象(通过@EnvironmentObject)正在触发完全不相关的视图中的绘制周期。 Modifying the User
's name in one view causes another view to re-render a long list of photos owned by the same User
(expensive operation). 在一个视图中修改
User
名会导致另一个视图重新渲染由同一User
拥有的一长串照片(昂贵的操作)。 What's worse - this happens with every keystroke typed . 更糟糕的是,每次键入击键都会发生这种情况。
Is SwiftUI smart enough to selectively redraw only views that display the mutated @Published property? SwiftUI是否足够聪明,可以有选择地重绘仅显示突变的@Published属性的视图?
Under the hood @ObservedObject
uses a Combine Subscriber
to observe your ObservableObject
. 在
@ObservedObject
使用组合Subscriber
观察ObservableObject
。
Consider this refactor of your Person
object: 考虑您的
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() {}
}
As you can see the Person
object "owns" a Publisher
assigned to objectWillChange
. 如您所见,
Person
对象“拥有”一个分配给objectWillChange
的Publisher
objectWillChange
。 And all @Property
is doing is removing some boilerplate from your object model by handling willSet
for you. @Property
所做的只是通过为您处理willSet
从对象模型中删除一些样板。
So ObservableObject
itself is not granular enough to detect a change to a particular property in your model but rather is "broadcasting" a change for any property change in your model and @ObservedObject
is simply subscribed to any change to your model. 因此,
ObservableObject
本身的粒度不足以检测模型中特定属性的更改,而是“广播”模型中任何属性更改的更改,而@ObservedObject
只是订阅了模型中的任何更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.