SwiftUI View повторно инициализирован, но свойство тела не вычисляется повторно, а представление не отображается повторно
Как можно повторно инициализировать представление в SwiftUI, но при этом тело не пересчитывается, а представление повторно отображается?
пример
import SwiftUI
struct ContentView: View {
var body: some View {
SubView()
.padding()
}
}
struct SubView: View {
@State private var items = [Int]()
init() {
print("SubView init")
}
var body: some View {
Text("\(items.count)")
Button("Add item") { items.append(Int.random(in: 0..<10)) }
Divider()
SubSubView()
SubSubView()
}
}
struct SubSubView: View {
init() {
print("SubSubView init")
}
var body: some View {
Text("I'm a subview") (>> _breakpoint here_)
}
}
Если я нажму 4 раза на кнопку, вид будет следующий:
Но у нас это есть в консоли:
SubView init (>> app launch)
SubSubView init (>> app launch)
SubSubView init (>> app launch)
SubSubView init
SubSubView init
SubSubView init
SubSubView init
SubSubView init
SubSubView init
SubSubView init
SubSubView init
SubSubView
body
свойство не пересчитывается (с использованием точки останова). Отображается ли этот SubSubView повторно только тогда, когда есть какие-либо изменения в зависимости представления, даже если он снова инициализирован?
1 ответ
Я не эксперт и у меня нет источников для этого, но я могу представить это примерно так:
Когда вы меняете
items
переменной, SwiftUI должен выяснить, какие подпредставления зависят от этого значения, чтобы их можно было повторно отобразить с правильными (обновленными) значениями. Один из простых способов узнать, изменился ли объект - это хеши. Итак, я думаю, что SwiftUI (внутренне) повторно инициализирует представление, вычисляет хэш над структурой и, если он отличается от хэша текущего представления, он повторно отображается. В противном случае изменение (из
items
) не повлиял на вид, поэтому его не нужно повторно отображать.
РЕДАКТИРОВАТЬ: для ясности вычисленное свойство (например,
body
) не инициализируется, когда инициализируется остальная часть объекта. Вычисляется по запросу. Поэтому в них можно использовать и другие переменные.