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

SwiftUI中在函数内访问@State变量取值不正确问题求助

问题原因与解决方案

核心原因

  • 最常见的诱因是自定义blinkBorder修饰符的异常操作:你给Image绑定了$leftRollEditing到blinkBorder的on参数,如果这个修饰符内部在动画执行、视图重绘过程中意外修改了绑定值,或是非预期重置了绑定值,就会导致你读取到的leftRollEditing不是预期的最新值。
  • 其次是SwiftUI视图重绘引发的状态读取时序问题:@State是托管在SwiftUI运行时的值类型属性,它的更新默认会触发视图重绘,如果你在updateRoll执行的同时刚好处于视图重绘周期内,重绘未完成时读取@State可能会拿到上一次渲染的旧值。
  • 还有概率较高的场景:你未列出的代码逻辑中存在其它同时修改leftRollEditing的操作,比如全局手势、父视图状态同步、onChange回调等,在你点击Edit Left Roll和点击Dice1按钮的间隙,状态被意外修改。

修复方案

  • 第一步先注释掉.blinkBorder(on: $leftRollEditing)这行代码验证问题来源,如果注释后状态读取恢复正常,直接排查blinkBorder的内部实现,确保它不会在非预期时机修改绑定值即可。
  • 第二步如果排除修饰符问题,可将@State替换为@StateObject托管的类对象属性,规避值类型状态在视图重绘时的读取时序问题,改造示例如下:
// 定义状态托管类
class ViewModel: ObservableObject {
    @Published var leftRollEditing = false
}

// 改造Home视图
struct Home: View {
    @StateObject private var vm = ViewModel()

    var body: some View {
      // ... 原有代码,所有用到leftRollEditing的地方替换为vm.leftRollEditing,绑定用$vm.leftRollEditing
      HStack {
         Button {
            updateRoll()
         } label: {
            Image("Dice1")
         }
      }
      HStack {
         VStack {
             Image("myImage")
                .padding()
                .blinkBorder(on: $vm.leftRollEditing)
             Text("MyText")
         }
      }
      HStack {
          Button {
              vm.leftRollEditing = true
          } label: {
              Text("Edit Left Roll")
          }
      }
   }

   func updateRoll() {
      if vm.leftRollEditing {
          vm.leftRollEditing = false
          //... 其他逻辑代码
      }
   }
}
  • 如果替换为类托管状态后仍存在问题,可以在所有修改leftRollEditing的位置添加打印日志,排查是否有未预期的状态修改逻辑,示例如下:
Button {
    vm.leftRollEditing = true
    print("设置leftRollEditing为true")
} label: {
    Text("Edit Left Roll")
}

func updateRoll() {
    print("updateRoll读取到的leftRollEditing:\(vm.leftRollEditing)")
    if vm.leftRollEditing {
        vm.leftRollEditing = false
        //... 其他逻辑代码
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:15:07