简体   繁体   English

swiftUI:在 onAppear 中更改 @State 崩溃

[英]swiftUI: Changing @State in onAppear crashes

I want to set a @State Variable if a View appears by calling a Service.如果通过调用服务出现视图,我想设置一个@State 变量。
Calling the Service in onAppear crashes the app.onAppear调用服务onAppear应用程序崩溃。
Calling the Service in a buttons action works fine.在按钮操作中调用服务工作正常。

struct ContentView: View {
  @State var dirContent : [String] = []

  var body: some View {
    VStack {
      List {
        ForEach(dirContent, id: \.self){
          fileName in
          Text(fileName)
        }
      }
      Button("Get Data"){self.dirContent = Service.getData()}
    }
    .onAppear{
    //self.dirContent = Service.getData2()   // Crashes!!
    }
  }
}

class Service{
  static func getData()->[String]{
    // ... get Data from somewhere
    return ["line1", "line2"]
  }

  static func getData2()->[String]{
    // ... get Data from somewhere
    return ["line4", "line5"]
  }
}

What's going wrong?怎么了?

the see why this happens, try to modify your code了解为什么会发生这种情况,请尝试修改您的代码

    var body: some View {
        VStack {
            List {
                ForEach(dirContent, id: \.self){
                    fileName in
                    Text(fileName).onAppear {
                        print("item appear")
                    }
                }
            }.onAppear {
                print("list appear")
            }
            Button("Get Data"){self.dirContent = Service.getData()}
        }
        .onAppear{
            print("content appear")
            DispatchQueue.main.async {
                self.dirContent = Service.getData2()
            }
        }
    }

the "old school" debug print shows us “老派”调试打印向我们展示了

content appear
list appear
item appear
item appear

Now it is clear, isn't it?现在很清楚了,不是吗?

I think I got it.我想我明白了。 The action has to be called asynchronously.该操作必须异步调用。

.onAppear{
  DispatchQueue.main.async {
    self.dirContent = Service.getData2()   
  }
}

Any Idea, why this isn't needed in the buttons action?任何想法,为什么在按钮操作中不需要这个?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM