Your code does not what you describe: The API scheduledTimer(withTimeInterval
adds the timer to the runloop implicitly. You must not add the timer to the runloop yourself. So both timers are running on the runloop.
I recommend to use DispatchSourceTimer
and a custom DispatchQueue
. The queue is serial by default and works as FIFO (first in first out). The serial queue guarantees that the tasks are not executed at the same time.
The timers are suspended after being created. You have to call activate()
(or resume()
in iOS 9 and lower) to start the timers for example in viewDidLoad
class Controller : UIViewController {
let queue = DispatchQueue(label: "myQueue")
lazy var timer1 : DispatchSourceTimer = {
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline:.now() + 1.0, repeating: 1.0)
timer.setEventHandler(handler: eventHandler1)
return timer
}()
lazy var timer2 : DispatchSourceTimer = {
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline:.now() + 0.5, repeating: 0.5)
timer.setEventHandler(handler: eventHandler2)
return timer
}()
override func viewDidLoad() {
super.viewDidLoad()
timer1.activate()
timer2.activate()
}
func eventHandler1() {
DispatchQueue.main.async {
// do stuff on the main thread
}
}
func eventHandler2() {
DispatchQueue.main.async {
// do stuff on the main thread
}
}
}
The timer properties are declared lazily to avoid optionals and the event handler closures (() -> Void
) are implemented as standard methods.