Swift数组控制台打印正常 SwiftUI Text显示报Index out of range错误
问题根因
- @State 变量
sumato初始化值为空数组[],View 首次渲染body时,网络异步请求还未返回结果,此时直接访问sumato[0]就会触发索引越界崩溃 - 点击 Button 时网络请求已经完成,
sumato已经被赋值为接口返回的非空数组,所以print语句不会报错 - 额外注意:URLSession 的 dataTask 回调默认在后台线程执行,直接给 UI 相关的 @State 变量赋值可能会导致页面不刷新甚至异常,需要切到主线程操作
修复方案
1. 数组取值替换为安全可选取值
不要直接用硬编码下标访问数组,改用数组的 first 可选属性,数组为空时会返回 nil,自动走后面的默认占位逻辑,完全避免越界:
Button(action: { // 点击前也加非空判断,避免请求未完成时点按钮报错 guard !sumato.isEmpty else { return } print(sumato[0].suma_ars) }){ // 用first替代[0]访问 Text(sumato.first?.suma_ars ?? "Start") }
2. 网络回调切主线程赋值
在网络请求的解码完成后,切主线程更新状态变量:
do { let resultado = try JSONDecoder().decode(Respuesta.self, from: data) // 切主线程更新UI相关状态 DispatchQueue.main.async { self.models = resultado.movimientos self.sumato = resultado.Sumas } } catch { print(error) }
可选优化:通用数组安全下标扩展
如果需要访问非0下标的元素,可以给Array加通用安全下标扩展,避免越界:
extension Array { subscript(safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } } // 使用示例:访问下标为2的元素 Text(sumato[safe: 2]?.suma_ars ?? "占位文本")
内容的提问来源于stack exchange,提问作者Juan Orrequia
相关产品推荐
相关产品推荐

