It's seems an odd phenomena, I tried both the reversed() method and Stride:
for num in stride(from: 20, to: 0, by: -1) {
//for num in (1...20).reversed() {
print("BEFORE DISPATCH \(num)")
DispatchQueue.main.asyncAfter(deadline: .now() + Double(num)) {
print("AFTER DISPATCH \(num)")
}
}
The only workaround I have is to print out "(20-num)".
I think I get what you're asking. I ran your code and I get the BEFORE DISPATCH part counting down, then I get the AFTER DISPATCH counting up. If you take out the + Double(num) that's creating the delay, then you get the AFTER DISPATCH in a countdown, too (almost instantaneously). Since your delay for the largest numbers are the longest, they come out last, and since this code is basically instantaneous you get the last ones that have the shortest delay finishing first (the lower numbers at the end) and working backward toward the ones with a longer delay. If you want this to go 20 down to 1 and then again but with a second tick in-between then have the delay set so the one with the biggest number has the shortest delay. That is, change your deadline: calculation to .now() + Double(20-num) so the 20 has the shortest delay of 0 and the 1 has the longest delay of 19.
The workaround? I’m not sure what the workaround is. Just making sure that the delay is set so the ones you’d like to start first have the shortest delay. Also keep in mind these timings are not a guarantee. I’m not sure exactly what the contract is but you definitely should not rely on them being down to the millisecond.