停用/使计时器失效



当用户按下后退按钮时,我试图Timer停用/无效,但当他按下下一个视图控制器时,我不会。

var timer = Timer()
                timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timePrinter), userInfo: nil, repeats: true)
                timer.fire()
override func viewWillDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if self.isMovingFromParentViewController{
        timer.invalidate()
    }
}

当用户按下后退按钮时,它不起作用。

当您将计划计时器与"目标/选择器"一起使用时,它会保留其目标。更具体地说,Runloop 保留了预定的计时器,而计时器又保留了它们的目标。

我使用这个版本,它不保留自己:

Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] _ in
    self?.doSomethingRegularly()
})

而且你仍然需要在deinit中使上述计时器失效,否则你会泄漏计时器(但不是你的类)。

Edit

Martin R提出了一个很好的观点:计时器将保留对视图控制器的强引用,因此我建议将timer.invalidate()放在视图控制器的deinit()方法中是行不通的。

Chris关于使用Timer 闭包版本的建议将解决这个问题,因此您可以将timer.invalidate()调用放入视图控制器的deinit()方法中。所以你也应该像克里斯的答案一样重写你的计时器代码。

——————————————

不要将计时器设为无效 viewWillDisappear(_:) .创建一个deinit方法并将其放在那里。当您按下后退按钮时,当前视图控制器应释放,并且 deinit 方法将触发。

deinit {
  timer.invalidate()
}

最新更新