I\'ve been searching for a way to use a Timer in Swift 4 and looked at this article. I test out my code in xcode and when the the timer first ticks (in this case after 10 se
As Andrea said, you should instantiate the timer in viewDidLoad
. Also the documentation says:
The selector should have the following signature:
timerFireMethod:
(including a colon to indicate that the method takes an argument).
And don't forget to disable this timer in, for example, viewDidDisappear
. You can't invalidate
it in deinit
because the repeating timer keeps a strong reference to its target, and your deinit
will not get called as long as the timer is running. And if you remove it in viewDidDisappear
, you might want to create the timer in viewDidAppear
.
Thus, resulting in something like:
class ViewController: UIViewController {
weak var timer: Timer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(tick(_:)), userInfo: nil, repeats: true)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
timer?.invalidate()
}
@objc func tick(_ timer: Timer) {
print("tick")
}
}
Or you can use the block-based rendition, with [weak self]
pattern, and the timer won't keep a strong reference to the view controller, in which case you can use deinit
:
class ViewController: UIViewController {
var timer: Timer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { [weak self] timer in // the `[weak self] reference is only needed if you reference `self` in the closure
print("tick")
}
}
deinit {
timer?.invalidate()
}
}