If I run the code below, it counts correctly to 10 and then skips every odd number.
If you let it run beyond 20, it will start skipping more and more (the output will be like 1-2-3-4-5-6-7-8-9-10-12-14-16-18-20-23-26-29 ...).
Couldn't find documentation of e.g. a limit of scheduled tasks, so asking you :) Learning SwiftUI since yesterday, so pardon if it's an obvious question.
If it's scheduled in a different DispatchQueue than main, it makes no difference.
Thanks for helping!
import SwiftUI
struct ContentView: View {
@State private var counter : Int = 0
func buttonTap() {
let time : DispatchTime = .now()
var delay : Double = 0
for _ in 1...50 {
delay = delay + 0.2
DispatchQueue.main.asyncAfter(deadline: time + delay) {
counter += 1
}
}
}
var body: some View {
ZStack {
Color(.black)
.edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
Text(String(counter))
.foregroundColor(.green)
.padding()
Text("Button")
.foregroundColor(.green)
.offset(y: 50)
.onTapGesture(perform: {
buttonTap()
})
}
}
}
That is an odd behavior, and it even occurs for much longer time intervals between events (for example, 2 seconds).
Consider using a Timer
instead:
You can use multiple single fire timers that work just like your separate dispatches:
func buttonTap() {
var delay : Double = 0
for _ in 1...50 {
delay = delay + 0.2
Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { timer in
self.counter += 1
}
}
}
or a single timer that fires every 0.2
seconds:
func buttonTap() {
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { timer in
self.counter += 1
if counter == 50 {
timer.invalidate()
}
}
}