If you run the code below, even after I invalidate the timer, the remaining code of the timer executes without any disruption. Why?
Is it because the closure has a strong reference to itself and is retained until it completely finishes itself? Or something else?
Does this mean invalidating a timer during its moment of execution does nothing?
class ViewController: UIViewController {
var timer : Timer?
let serialQueue = DispatchQueue(label: "com.createTimer.serial")
override func viewDidLoad() {
super.viewDidLoad()
serialQueue.sync { [weak self] in
self?.timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: false, block: { [weak self] _ in
self?.someDummyFunc()
print("yyy")
print("\(self?.timer?.isValid)")
})
}
}
func someDummyFunc(){
print("\(timer?.isValid)")
print("xxx")
timer?.invalidate()
}
}
The prints that I get from running this code is:
Optional(true)
xxx
yyy
Optional(false) // timer.isValid is false !!!
Yet what I initially thought I would get is:
Optional(true)
xxx
The scheduledTimer(withTimeInterval:repeats:block:)
method:
After
interval
seconds have elapsed, the timer fires, executingblock
.
The invalidate()
method:
Stops the timer from ever firing again
You are correct in your discovery that invalidating a timer will not interrupt a currently executing block, but will only prevent future executions of that block.