![](/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.