计时器在 invalidate() 和 nil 之后继续工作

Timer keeps working after invalidate() and nil

我有这个计时器:

class InstallationViewController: BaseViewController {

   var precentageTimer: Timer!
}

在同一个 class 中,我像这样启动计时器:

               self.precentageTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { (timer) in
                self.network.getClibrationPercentage(success: { (info, percent) in
                    self.isAnalysisCompleted(percent: percent)
                    self.precentageLbl.text = "\(percent)%"
                    self.instructionsLbl.text = info
                    self.precentageLbl.isHidden = false
                }, failure: { (error) in
                    print(error)
                })
            })

我也有这个解散任务的方法:

 func dissmissAllTasks() {
    NotificationCenter.default.removeObserver(self)
    self.setCalibrationEnableTimer?.invalidate()
    self.setCalibrationEnableTimer = nil
    self.snapShotTimer?.invalidate()
    self.snapShotTimer = nil
    self.precentageTimer?.invalidate()
    self.precentageTimer = nil
}

当我像这样单步执行 viewWillDisappear 时会发生这种情况:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    dissmissAllTasks()
 }

但是当我去其他地方时 VC 我可以看到这个计时器一直在走。 我检查了调用的 dissmissAllTask​​s(),我可以看到计时器为零。

为什么计时器一直在走?

确保在同一个线程中创建和使计时器失效。

此外,您还 self 在闭包中捕获了强引用,因此我相信对您的计时器的引用仍然存在。 你在 0.1 秒内从服务器得到了一些重复的东西,你所有的请求似乎也是活的。

您几乎可以肯定分配了两次 precentageTimer 而没有在其间使它无效。这是一个很常见的错误。在调用 viewWillDisappear 之前,可能已多次调用包含 self.precentageTimer = 的函数。由于您将其与按钮按下相关联,因此如果按钮被按下两次,则可能会发生这种情况。

通常的解决办法是像这样在percentageTimer上加一个willSet(你不希望percentageTimer变成!;绝对应该是? 因为它可以合法地为 nil):

var precentageTimer: Timer? {
    willSet {
        percentageTimer?.invalidate()
    }
}