【发布时间】:2020-11-18 12:48:51
【问题描述】:
当行嵌入到像堆栈或NavigationLink 这样的容器中时,SwiftUI 似乎不会为列表行保留@StateObjects。这是一个例子:
class MyObject: ObservableObject {
init() { print("INIT") }
}
struct ListView: View {
var body: some View {
List(0..<40) { _ in
NavigationLink(destination: Text("Dest")) {
ListRow()
}
}
}
}
struct ListRow: View {
@StateObject var obj = MyObject()
var body: some View {
Text("Row")
}
}
当您向下滚动列表时,您会看到 "INIT" 记录了每个出现的新行。但是向上滚动,您会看到 "INIT" 再次记录每一行 - 即使它们已经出现了。
现在删除NavigationLink:
List(0..<40) { _ in
ListRow()
}
并且@StateObject 的行为与预期一致:每一行只有一个"INIT",没有重复。 ObservableObject 在视图刷新时保持不变。
SwiftUI 在持久化@StateObjects 时遵循什么规则?在此示例中,MyObject 可能正在存储重要的状态信息或下载远程资产 - 那么我们如何确保每行仅发生一次(与 NavigationLink 等结合使用时)?
【问题讨论】:
-
ListRow可能不应该存储任何@StateObjects。相反,它们应该保留在行的外部,然后在初始化ListRow时传入。