当显示包含在所述选项卡不可见时更改的数据的选项卡时,SwiftUI TabView 崩溃
SwiftUI TabView crashes when displaying tab containing data that changed when said tab was invisible
一个 SwiftUI TabView 包含两个选项卡。每个显示来自同一模型的数据。如果数据丢失,则显示 ProgressView,如果数据存在,则显示当前值。
在示例模型中,数据在 2 秒后异步设置导致问题。 (在我的真实应用中,数据是作为异步调用的结果设置的。)
在 运行 应用程序之后,第一个选项卡显示包含 ProgressView,数据在 2 秒后显示。到目前为止,一切似乎都有效。
当从第一个选项卡切换到第二个选项卡时,应用程序在 SwiftUI 显示代码的 75 层深处崩溃:
(AG::Graph::add_indirect_attribute:) with EXC_BAD_ACCESS.
我做错了什么,如果是 SwiftUI 错误,我该如何规避问题?
以下代码导致崩溃:
import SwiftUI
import Combine
class Model: ObservableObject{
@Published var value:Double?
init(){
DispatchQueue.main.asyncAfter(deadline: .now() + 3){
self.value = 2.0
print("value set")
}
}
}
@main
struct TabViewUpdatingTestApp: App {
@StateObject var model = Model()
var body: some Scene {
WindowGroup {
ContentView(model: model)
}
}
}
struct Tab: View {
let name:String
@ObservedObject var model:Model
var body: some View {
if let mvalue = model.value{
Text("name: \(name), value: \(mvalue)")
}else{
ProgressView().font(.largeTitle)
}
}
}
struct ContentView: View {
@ObservedObject var model:Model
var body: some View {
TabView {
Tab(name: "Tab 1", model: model)
.tabItem {
Label("Tab 1", systemImage: "1.circle")
}
Tab(name: "Tab 2", model: model)
.tabItem {
Label("Tab 2", systemImage: "2.circle")
}
}
}
}
我觉得这像是一个错误。一种可能的解决方法是强制刷新 TabView
:
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
TabView {
Tab(name: "Tab 1", model: model)
.tabItem {
Label("Tab 1", systemImage: "1.circle")
}
Tab(name: "Tab 2", model: model)
.tabItem {
Label("Tab 2", systemImage: "2.circle")
}
}
.id(model.value) // add here
}
}
或者,您可以创建一些仅更改一次的其他变量,而不是在 model.value
更改时重新绘制视图(因此您不必每次都刷新 TabView
,而是在开始)。
一个 SwiftUI TabView 包含两个选项卡。每个显示来自同一模型的数据。如果数据丢失,则显示 ProgressView,如果数据存在,则显示当前值。 在示例模型中,数据在 2 秒后异步设置导致问题。 (在我的真实应用中,数据是作为异步调用的结果设置的。)
在 运行 应用程序之后,第一个选项卡显示包含 ProgressView,数据在 2 秒后显示。到目前为止,一切似乎都有效。 当从第一个选项卡切换到第二个选项卡时,应用程序在 SwiftUI 显示代码的 75 层深处崩溃:
(AG::Graph::add_indirect_attribute:) with EXC_BAD_ACCESS.
我做错了什么,如果是 SwiftUI 错误,我该如何规避问题?
以下代码导致崩溃:
import SwiftUI
import Combine
class Model: ObservableObject{
@Published var value:Double?
init(){
DispatchQueue.main.asyncAfter(deadline: .now() + 3){
self.value = 2.0
print("value set")
}
}
}
@main
struct TabViewUpdatingTestApp: App {
@StateObject var model = Model()
var body: some Scene {
WindowGroup {
ContentView(model: model)
}
}
}
struct Tab: View {
let name:String
@ObservedObject var model:Model
var body: some View {
if let mvalue = model.value{
Text("name: \(name), value: \(mvalue)")
}else{
ProgressView().font(.largeTitle)
}
}
}
struct ContentView: View {
@ObservedObject var model:Model
var body: some View {
TabView {
Tab(name: "Tab 1", model: model)
.tabItem {
Label("Tab 1", systemImage: "1.circle")
}
Tab(name: "Tab 2", model: model)
.tabItem {
Label("Tab 2", systemImage: "2.circle")
}
}
}
}
我觉得这像是一个错误。一种可能的解决方法是强制刷新 TabView
:
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
TabView {
Tab(name: "Tab 1", model: model)
.tabItem {
Label("Tab 1", systemImage: "1.circle")
}
Tab(name: "Tab 2", model: model)
.tabItem {
Label("Tab 2", systemImage: "2.circle")
}
}
.id(model.value) // add here
}
}
或者,您可以创建一些仅更改一次的其他变量,而不是在 model.value
更改时重新绘制视图(因此您不必每次都刷新 TabView
,而是在开始)。