我正在实例化这样一个计时器:
func runTimer() {
DispatchQueue.main.async {
if self.timer.isValid == false {
self.timer = Timer.scheduledTimer(timeInterval: 0.025, target: self, selector: (#selector(ResultVCViewController.updateTimer)), userInfo: nil, repeats: true)
RunLoop.current.add(self.timer, forMode: .commonModes)
}
}
}
并像这样解除分配:
func stopTimer() {
DispatchQueue.main.async {
if self.timer.isValid {
self.timer.invalidate()
self.isTimerRunning = false
print("stopped timer")
} else {
print("timer isn't running!")
}
}
}
当这样调用时,stopTimer()
没有被调用(没有控制台输出,计时器仍在运行,如果我添加一个断点,它被忽略但是执行了segue):
@IBAction func aboutLicensebtn(_ sender: UIBarButtonItem) {
//debug
stopTimer()
performSegue(withIdentifier: "AboutLicense", sender: nil)
}
这可以按预期工作:
@IBAction func goBack(_ sender: UIBarButtonItem) {
stopTimer()
self.dismiss(animated: true, completion: nil)
}
如何在执行segue时停止计时器?
编辑:计时器在放入viewDidDisappear
时停止,但我不想要这种行为。
编辑:我也尝试在main上执行segue,但结果没有改变。
澄清为什么我按照我的方式开始和停止计时器:
它被添加到RunLoop
以用于.commonModes
,因此在滚动视图时计时器不会停止。
它在main上启动并停止,以确保它在同一个线程上启动和停止。
答案 0 :(得分:3)
不将计划的计时器添加到runloop。
启动和停止计时器的最可靠方法是使用可选属性并检查它(根本不需要调度到主队列):
func runTimer() {
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: 0.025,
target: self,
selector: #selector(updateTimer),
userInfo: nil,
repeats: true)
}
}
func stopTimer() {
if timer != nil {
timer!.invalidate()
timer = nil
print("stopped timer")
} else {
print("timer isn't running!")
}
}
05:00:00