If targeting iOS version 10 and greater, you can use the block-based rendition of Timer, which simplifies the potential strong reference cycles, e.g.:
weak var timer: Timer?
func startTimer() {
timer?.invalidate() // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it
timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in
// do something here
}
}
func stopTimer() {
timer?.invalidate()
}
// if appropriate, make sure to stop your timer in `deinit`
deinit {
stopTimer()
}
While Timer is generally best, for the sake of completeness, I should note that you can also use dispatch timer, which is useful for scheduling timers on background threads. With dispatch timers, since they're block-based, it avoids some of the strong reference cycle challenges with the old target/selector pattern of Timer, as long as you use weak references.
So:
var timer: DispatchSourceTimer?
func startTimer() {
let queue = DispatchQueue(label: "com.domain.app.timer") // you can also use `DispatchQueue.main`, if you want
timer = DispatchSource.makeTimerSource(queue: queue)
timer!.schedule(deadline: .now(), repeating: .seconds(60))
timer!.setEventHandler { [weak self] in
// do whatever you want here
}
timer!.resume()
}
func stopTimer() {
timer = nil
}
For more information, see the the Creating a Timer section of Dispatch Source Examples in the Dispatch Sources section of the Concurrency Programming Guide.
This is specially useful for when you need to dispatch on a particular Queue. Also, if you're planning on using this for user interface updating, I suggest looking into CADisplayLink as it's synchronized with the GPU refresh rate.
If you can allow for some time drift here's a simple solution executing some code every minute:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Just run executeRepeatedly() once and it'll be executed every minute. The execution stops when the owning object (self) is released. You also can use a flag to indicate that the execution must stop.