You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么SwiftUI中解码JSON得到的数据无法赋值给State变量?

问题原因及修复方案

直接崩溃原因

  • addItem方法执行时,self.names是空数组,你生成随机下标用到的范围0..<self.names.count在数组长度为0时是无效区间,直接触发数组越界崩溃。

names无法赋值的核心原因

  • 你在ContentView的init方法中发起了异步网络请求,而@State修饰的属性在View初始化阶段还没有完成和视图生命周期的绑定,此时异步回调中对@State属性的赋值大概率不会生效,也无法触发视图更新。
  • 你的代码错误吞掉了所有异常:网络请求失败的guard判断直接return,JSON解码的catch块为空,不管是网络出错、返回数据异常还是JSON结构不匹配导致解码失败,你都无法感知到问题,自然也不会走到赋值逻辑。

修复方案

  1. 把getNames的调用从init移到onAppear修饰符中
  2. 给addItem加数组非空判断,避免越界
  3. 补充错误日志输出,方便排查问题
  4. 避免强制解包、强制try的写法,减少崩溃风险

修复后参考代码

struct ContentView: View {
  @State var names:[String] = []
  @Environment(\.managedObjectContext) private var viewContext
  
  var body: some View {
      List {
          // 展示CoreData的Person对象逻辑
      }
      Button(action: addItem)
      .onAppear {
          getNames()
      }
  }

  func getNames(){
    // URL & JSON 初始化逻辑
    session.dataTask(with: request) { data, response, error in
        if let error = error {
            print("网络请求失败: \(error)")
            return
        }
        guard let data = data else {
            print("返回数据为空")
            return
        }
        do {
            let decoder = JSONDecoder()
            let decodedNames = try decoder.decode([String].self, from: data)
            DispatchQueue.main.async {
                self.names = decodedNames
            }
        }
        catch {
            print("JSON解码失败: \(error)")
        }
    }.resume()
  }
  
  func addItem() {
      guard !names.isEmpty else {
          print("名字列表还未加载完成")
          return
      }
      let p = Person(context: viewContext)
      p.age = String(Int.random(in: 1...100))
      p.name = self.names[Int.random(in: 0..<self.names.count)]
      do {
          try viewContext.save()
      } catch {
          print("CoreData保存失败: \(error)")
      }
  }
}

内容的提问来源于stack exchange,提问作者dooblr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:27:03