swahili
(Swahili)
1
I'm testing a timer that is returning two fired messages when I only expect one at each time or trigger:
let queue = DispatchQueue(label: "com.domain.app.timer", qos: .userInteractive)
let timer = DispatchSource.makeTimerSource(flags: .strict, queue: queue)
timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .nanoseconds(0))
var elapsedTime = DispatchTime.now().uptimeNanoseconds
timer.setEventHandler {
elapsedTime = DispatchTime.now().uptimeNanoseconds - elapsedTime
print("Timer Fired: elapsedTime: \(elapsedTime/1000000000)")
}
timer.resume()
The output is:
**Timer Fired: elapsedTime: 0**
**Timer Fired: elapsedTime: 131188**
**Timer Fired: elapsedTime: 1**
**Timer Fired: elapsedTime: 131189**
**Timer Fired: elapsedTime: 2**
**Timer Fired: elapsedTime: 131190**
**Timer Fired: elapsedTime: 3**
**Timer Fired: elapsedTime: 131191**
**Timer Fired: elapsedTime: 4**
**Timer Fired: elapsedTime: 131192**
**Timer Fired: elapsedTime: 5**
**Timer Fired: elapsedTime: 131193**
What's the second value per call?
I tried your code, it fires once per second, as expected. But your elapsedTime computation is a little fishy. Try this:
var last = DispatchTime.now().uptimeNanoseconds
timer.setEventHandler {
let current = DispatchTime.now().uptimeNanoseconds
let elapsed = current - last
last = current
print("Timer Fired: elapsedTime: \(Double(elapsed)/1000000000)")
}
PS
I don't know how you run it, but there's no runloop in your sample code, so I use dispatchMain for that.
Another thing. If you don't plan to relax the firing time, you don't need to specify leeway value (which is already 0 by default). Even if you specify leeway of 0, it's not strictly guaranteed that it will fire at/before the deadline.
swahili
(Swahili)
3
Yours works fine! Thanks once again @Lantua
Yeh, I was using the PlayGround, sorry. So, I thought this part was fine:
elapsedTime = DispatchTime.now().uptimeNanoseconds - elapsedTime
where elapsedTime is a mutable variable outside the setEventHandler, was that the problem? Do I have to keep all values in separate variables in Swift? I thought it'd compute and update elapsedTime for each subsequent call...
Well, umm, I think your understanding of the variable works fine, and every call does use the shared elapsedTime. Just that the way you compute it doesn't make much sense. Try to hand-calculate it on the paper for the first few values and you might see. With now returning something like 0s, 1s, 2s, etc.
swahili
(Swahili)
5
You're right, haven't noticed and that was the problem; Thank you : )