传递到 DispatchQueue 后变量变为 0(在模拟器中工作。实际设备中为 0)

Variables becoming 0 after passing into DispatchQueue (works in Simulator. 0 in actual device)

变量(以秒为单位的锻炼时间)没有传递到 GCD 函数调用的代码有问题。但是 workoutStartDateTime 毫无问题地通过了。这是我正在使用的代码。

  var seconds: Int = 0
  var workoutStartDateTime: Date?


  func finishWorkout() {
    print("0 FinishWorkout:\(seconds) workoutStartDateTime:\(workoutStartDateTime)")
    
    DispatchQueue.global(qos: .utility).async { [self] in
      print("1 FinishWorkout:\(self.seconds) workoutStartDateTime:\(workoutStartDateTime)")
      TCXfuncs.writeTCX(workoutStartDateTime: workoutStartDateTime!, seconds: seconds)
      
    }

这是打印出来的内容

0 FinishWorkout:3 workoutStartDateTime:Optional(2021-01-28 03:05:29 +0000)
1 FinishWorkout:0 workoutStartDateTime:Optional(2021-01-28 03:05:29 +0000)
// I also placed a print statement into the TCXFunc function to verify.
TCXExportFunction seconds:0

奇怪的是,当我在模拟器中 运行 它时,它起作用了。经过的秒数。

0 FinishWorkout:3 workoutStartDateTime:Optional(2021-01-28 03:05:29 +0000)
1 FinishWorkout:3 workoutStartDateTime:Optional(2021-01-28 03:05:29 +0000)
// I also placed a print statement into the TCXFunc function to verify.
TCXExportFunction seconds:3

编辑:(和解决方案)

经过多次尝试和 SO/Googles,我找到了这个 SO --> 并使用了这个 works。现在的问题是 为什么

  func finishWorkout() {
    let mySec = seconds
    print("0 FinishWorkout:\(seconds) mySec:\(mySec) workoutStartDateTime:\(workoutStartDateTime)")
    
    DispatchQueue.global(qos: .utility).async { [self] in
      print("1 FinishWorkout:\(self.seconds) mySec:\(mySec)  workoutStartDateTime:\(workoutStartDateTime)")
      TCXfuncs.writeTCX(workoutStartDateTime: workoutStartDateTime!, seconds: mySec) // << Pass the "helper" variable
      
    }

这是结果输出。您可以看到 119 在第二次打印时变为“0”,使用“helper”变量使其正确。为什么……?

0 FinishWorkout:119 mySec:119 workoutStartDateTime:Optional(2021-01-28 04:04:33 +0000)
1 FinishWorkout:0   mySec:119 workoutStartDateTime:Optional(2021-01-28 04:04:33 +0000)
// I also placed a print statement into the TCXFunc function to verify.

writeTCX Passed seconds:119 Date:2021-01-28 04:04:33 +0000 

我认为这是一个时间问题。 “dispatch.async()”调用的意思是“在将来某处执行此操作”。这可能很快(微秒)甚至很晚(毫秒),但您应用的其他部分可能会同时重置“秒”。

当您在提交调度调用之前将当前内容“保存”到局部变量中时,只要调度项目开始工作,您就可以使用此值。

还有一个一般性提示:有一条“铁律”……永远不要处理不同队列中的变量……或者只是有时……副作用太复杂,可能会在未来的版本中引起问题。 .