我有一个简单的视图,就是通过@ObservedObject属性观察一个对象。 像这样的东西:
struct BrowserView: View {
@ObservedObject var fs: FileStore
var body: some View {
List(fs.files) { file in
NavigationLink(destination: BrowserView(fs: self.fs) {
FileRow(item: file)
}
}
.onAppear(perform: loadFiles)
}
private func loadFiles() {
fs.loadFiles()
}
}
因此,当一行被点击时,我会导航到下一个视图,它仍然是同一个BrowserView,使用相同的数据集(在实际代码中,它也传递其他值,就像文件浏览器和C一样,当前路径也会作为参数传递,但为了示例起见,它实际上并不相关)。
问题在于,当下一个BrowserView出现时,数据集会发生变化,而这些变化会触发上一个视图的更新,而上一个视图不再可见,试图更新它的UITableView实际上会使应用程序崩溃。
有什么方法可以告诉视图禁用它在OnDisome或类似的东西中的绑定吗? 如果不是,当只有一个模型(存储)在不同视图之间共享时,正确的模式是什么?
更新
下面是当新视图被推送到堆栈上并且新数据已经被检索时所发生的崩溃日志:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x00000001b9a4643c in AG::Graph::import_attribute(AG::Subgraph*, AG::Graph&, AG::attribute_t, AGTypeID, AG::ClosureFunctionVV<void>, AG::ClosureFunctionFV<void, AG::ClosureFunctionVV<void> >) ()
#1 0x00000001b9a4c76c in AGGraphImportAttribute ()
#2 0x00000001c52b8280 in ViewGraph.import<A>(_:as:from:) ()
#3 0x00000001c53a9a20 in static StyleType.makeViewList<A>(view:style:inputs:) ()
#4 0x00000001c53a9200 in static ResolvedList._makeViewList(view:inputs:) ()
#5 0x00000001c5203544 in closure #2 in static ModifiedContent<>._makeViewList(view:inputs:) ()
#6 0x00000001c51e723c in specialized static MultiViewModifier._makeViewList(modifier:inputs:body:) ()
#7 0x00000001c51e8274 in protocol witness for static ViewModifier._makeViewList(modifier:inputs:body:) in conformance ButtonActionModifier ()
#8 0x00000001c52020d8 in static ModifiedContent<>._makeViewList(view:inputs:) ()
#9 0x00000001c5203544 in closure #2 in static ModifiedContent<>._makeViewList(view:inputs:) ()
#10 0x00000001c51e81dc in static ViewModifier<>._makeViewList(modifier:inputs:body:) ()
#11 0x00000001c52020d8 in static ModifiedContent<>._makeViewList(view:inputs:) ()
#12 0x00000001c51795c0 in static View.makeViewList(view:inputs:) ()
#13 0x00000001c516b42c in static View._makeViewList(view:inputs:) ()
#14 0x00000001c542524c in AnyViewStorage.makeViewList(view:inputs:) ()
#15 0x00000001c54268a8 in closure #1 in AnyViewList.update(context:) ()
#16 0x00000001c5426648 in AnyViewList.update(context:) ()
#17 0x00000001c54289a0 in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance AnyViewList ()
#18 0x00000001b9a3b88c in AG::Graph::UpdateStack::update() ()
#19 0x00000001b9a3bd48 in AG::Graph::update_attribute(unsigned int, bool) ()
#20 0x00000001b9a40cb0 in AG::Subgraph::update(unsigned int) ()
#21 0x00000001c52be0f4 in ViewGraph.runTransaction(in:) ()
#22 0x00000001c52bdea8 in closure #1 in ViewGraph.flushTransactions() ()
#23 0x00000001c52bdb20 in ViewGraph.flushTransactions() ()
#24 0x00000001c52bdc98 in closure #1 in closure #1 in ViewGraph.asyncTransaction<A>(_:mutation:style:) ()
#25 0x00000001c55759c0 in ViewRendererHost.updateViewGraph<A>(body:) ()
#26 0x00000001c52bdc60 in closure #1 in ViewGraph.asyncTransaction<A>(_:mutation:style:) ()
#27 0x00000001c52d9a30 in thunk for @escaping @callee_guaranteed () -> () ()
#28 0x00000001c514ff64 in static NSRunLoop.flushObservers() ()
#29 0x00000001c514fed4 in closure #1 in static NSRunLoop.addObserver(_:) ()
#30 0x00000001c5150004 in @objc closure #1 in static NSRunLoop.addObserver(_:) ()
#31 0x000000018d7acee8 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#32 0x000000018d7a7b78 in __CFRunLoopDoObservers ()
#33 0x000000018d7a8018 in __CFRunLoopRun ()
#34 0x000000018d7a78f4 in CFRunLoopRunSpecific ()
#35 0x0000000197bbe604 in GSEventRunModal ()
#36 0x000000019197b358 in UIApplicationMain ()
你所描述的应该不会造成撞车。。。 请尝试以下代码:
class Model: ObservableObject {
@Published var files: [String] = ["red", "black", "blue", "yellow", "orange"]
}
struct ContentView: View {
var body: some View {
NavigationView {
MainView(fs: Model())
}
}
}
struct MainView: View {
@ObservedObject var fs: Model
var body: some View {
VStack {
List(fs.files, id: \.self) { file in
NavigationLink(destination: MainView(fs: self.fs)) {
Text(file)
}
}.onAppear {
self.fs.files.append("New Value")
}
}
}
}
它观察一个模型并在OnExpect中进行更新,并且一次又一次地推送相同的视图只会更新下一个屏幕和第一个屏幕中的列表。