简体   繁体   English

为什么 SwiftUI 没有设置来自解码 JSON 的 state 变量?

[英]Why is SwiftUI not setting a state variable from decoded JSON?

I am trying to download a JSON list of first names and use them to randomly pick a name.我正在尝试下载 JSON 名字列表并使用它们随机选择一个名字。 However when I step through in the debugger I see that self.names is not being set to the parsed JSON. Why is this?但是,当我在调试器中单步执行时,我发现 self.names 未设置为已解析的 JSON。这是为什么?

struct ContentView: View {

  @State var names:[String] = []
  init(){
      getNames()
  }
  var body: some View {
      List {displays person objects from coredata}
      Button(action: addItem)
  }

  func getNames(){
    // URL & JSON setup
    session.dataTask(with: request) { data, response, error in
        guard error == nil else {return}
        do {
            let decoder = JSONDecoder()
            let decodedNames = try decoder.decode([String].self, from: data!)
            DispatchQueue.main.async {
                self.names = decodedNames // self.names not being set here
            }
        }
        catch {}
    }.resume()
  }
  
  func addItem() {
      let p = Person(context: viewContext)
      p.age = String(Int.random(in: 1...100))
      p.name = self.names[Int.random(in: 0..<self.names.count)] // crashes here
      try! viewContext.save()
  }
  

Views in SwiftUI do not have a guaranteed lifespan. SwiftUI 中的视图没有保证的生命周期。 They're transitive by nature and the system can rebuild them at any time.它们本质上是可传递的,系统可以随时重建它们。 If you have an asynchronous method in a View, there is no guarantee that this same instance of the View will exist in the hierarchy by the time it returns.如果视图中有异步方法,则不能保证视图的同一实例在返回时会存在于层次结构中。

For this reason, it's generally recommended that you move asynchronous code to a view model ( ObservableObject with a @Published property).出于这个原因,通常建议您将异步代码移动到视图 model(具有@Published属性的ObservableObject )。 The ObservableObject will have a guaranteed lifespan and can communicate the data back to the view via the @Published property. ObservableObject将具有保证的生命周期,并且可以通过@Published属性将数据传回视图。

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

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