当用户按下后退按钮时,我试图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()
}