Search code examples
iosswiftgrand-central-dispatch

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


There something wrong w/ the code that variables (workout time in seconds) are not getting passed into the GCD function call. But the workoutStartDateTime gets passed w no issues. Here's the code that I'm using.

  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)
      
    }

This is what gets printed out

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

The odd thing is, when I run it in the simulator, it works. The number of seconds get passed.

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

Edit: (and solution)

After many tries and SO/Googles, I found this SO --> https://stackoverflow.com/a/31566063/14414215 and using this works. Now the question would be Why

  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
      
    }

This is the resultant output. You can see that the 119 becomes "0" in the 2nd print out with the "helper" variable gets it correct. Why.....?

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 

Solution

  • I think it's a timing issue. The "dispatch.async()" call, means "do this somewhere in the future". This might be very soon (micro seconds) or even very late (milli seconds), but there might be other parts of your app, which resets the "seconds" meanwhile.

    When you "save" the current content into a local variable BEFORE you submit the dispatch call, you have this value available, whenever the dispatch item will come to work.