Здесь есть две проблемы:
- SwiftUI использует типы значений, которые инициализируются снова и снова при каждом проходе через
body
. - Относится к # 1,
NavigationLink
не ленивый.
# 1
Новый ListObj
создается каждый раз, когда вы звоните ViewA.init(...)
. ObservedObject
не работает так же, как @State
, где SwiftUI тщательно следит за ним на протяжении всего жизненного цикла на экране. SwiftUI предполагает, что окончательное владение @ObservedObject
существует на некотором уровне выше View
, в котором он используется.
Другими словами, вы почти всегда должны избегать таких вещей, как @ObservedObject var myObject = MyObservableObject()
.
(Обратите внимание, что даже если вы сделали @State var model = ListObj()
, он будет создаваться каждый раз. Но так как @State
SwiftUI заменит новый экземпляр оригиналом до вызова body
.)
# 2
Кроме того, NavigationLink
не ленив. Каждый раз, когда вы создаете экземпляр NavigationLink
, вы передаете только что созданный экземпляр ViewA
, который создает экземпляр вашего ListObj
.
Итак, для начала одну вещь, которую вы можете сделать, это сделать LazyView
, чтобы отложить инстанцирование до тех пор, пока NavigationLink.destination.body
фактически не будет вызвано:
// Use this to delay instantiation when using `NavigationLink`, etc...
struct LazyView<Content: View>: View {
var content: () -> Content
var body: some View {
self.content()
}
}
Теперь вы можете сделать NavigationLink(destination: LazyView { ViewA() })
и инстанцирование ViewA
будет отложено до фактического отображения destination
.
Простое использование LazyView
исправит вашу текущую проблему , пока это вид сверху в иерархии , например это когда вы набираете sh его в NavigationView
или если вы его представляете.
Тем не менее, именно здесь приходит комментарий @ user3441734. Что вам действительно нужно сделать, так это сохранить право собственности на model
где-то за пределами вашего View
из-за того, что было объяснено в # 1.