繁体   English   中英

SwiftUI-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对象“拥有”一个分配给objectWillChangePublisher objectWillChange @Property所做的只是通过为您处理willSet从对象模型中删除一些样板。

因此, ObservableObject本身的粒度不足以检测模型中特定属性的更改,而是“广播”模型中任何属性更改的更改,而@ObservedObject只是订阅了模型中的任何更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM