Swift:调用invalidate后计时器未停止反而加速?
问题分析与解决方案
嘿,我一眼就揪出你这个秒表加速问题的根源啦!
问题原因
你每次点击「Start Timer」按钮时,都会创建一个全新的Timer实例,但之前已经在运行的Timer并没有被正确终止。举个具体场景:
- 第一次点Start,创建了Timer A,它会每秒调用
updateTimer让counter加0.1; - 要是不小心快速点了两次Start(哪怕按钮刚要被禁用前),Timer变量会被覆盖成新的Timer B,而Timer A还在后台偷偷运行;
- 这时候两个Timer会同时触发
updateTimer,counter每秒就会加0.2,看起来就是「加速」了; - 点击Start的次数越多,同时运行的Timer就越多,秒表速度自然越来越快。
而且你的pauseButton里虽然调用了timer.invalidate(),但这个方法只能终止最后一次创建的Timer,之前多出来的Timer依然在后台跑,根本没被管控到。
修复方案
只需要在创建新Timer前,先确保旧的Timer已经被停止并清理掉,同时完善Timer的管理逻辑:
1. 修改playButton方法,创建新Timer前先终止旧Timer
@objc func playButton(_ sender : Any) { // 先停止已有计时器,避免多个实例同时运行 if timer != nil { timer.invalidate() timer = nil } timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true) startButton.isEnabled = false stopButton.isEnabled = true isRunning = true self.view.addSubview(stopButton) startButton.isHidden = true stopButton.isHidden = false }
2. 完善pauseButton方法,终止Timer后置空变量
@objc func pauseButton(_ sender: Any) { self.view.addSubview(startButton) timer.invalidate() timer = nil // 置空避免野指针,也能帮助后续判断Timer状态 stopButton.isHidden = true startButton.isHidden = false startButton.isEnabled = true stopButton.isEnabled = false isRunning = false }
额外小建议
你的Timer时间间隔设的是1秒,但updateTimer里每次给counter加0.1,这逻辑有点矛盾(秒表每秒只跳0.1?)。如果是想做0.1秒精度的秒表,应该把Timer的timeInterval改成0.1,这样逻辑更合理:
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
总结
核心问题就是重复创建Timer却未清理旧实例,导致多个Timer同时触发更新方法。只要在创建新Timer前确保旧Timer已经被停止并置空,就能彻底解决秒表加速的问题啦!
内容的提问来源于stack exchange,提问作者vgvishesh23113
相关产品推荐
相关产品推荐

