取消/无效计时器

Nit*_*esh 1 nstimer uinavigationcontroller ios swift swift3

我试图Timer在用户按下后退按钮时取消初始化/无效,但在他按下下一个ViewController时不尝试取消初始化/无效。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

当用户按下返回按钮时,它不起作用。

Dun*_*n C 5

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

deinit {
  timer.invalidate()
}
Run Code Online (Sandbox Code Playgroud)

  • @Nitesh,如果 `deinit()` 没有被触发,那么你的 vc 没有被释放,这意味着你持有对它的强引用。检查您的代码,尤其是闭包(确保在闭包中使用对 vc 的弱引用)。 (2认同)
  • 简单地使 `deinit` 中的时间无效可能是行不通的。计时器在运行时*保留*其目标,因此不会释放视图控制器并且不会调用 deinit。 (2认同)

Chr*_*ris 5

当您将排定计时器与“目标/选择器”一起使用时,它将保留其目标。更具体地说,Runloop保留计划的计时器,这些计时器又保留其目标。

我使用此版本,该版本不保留自身:

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

而且您仍然需要在deinit中使上述计时器无效,否则您将泄漏计时器(但不会泄漏您的班级)。