Экран закрыт, но tick продолжает срабатывать и deinit не вызывается
Экран плеера обновляет прогресс раз в секунду.
final class PlayerViewController: UIViewController {
private var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(tick),
repeats: true)
}
@objc private func tick() { }
deinit { timer?.invalidate() }
}
Пользователь уходит с экрана, но deinit не вызывается, а tick продолжает срабатывать. В чём причина и что исправит ситуацию?
- Таймер удерживается RunLoop и сам сильно держит target: invalidate нужно звать при уходе с экрана
- Достаточно объявить свойство как weak var timer — тогда таймер освободится вместе с контроллером
- Нужно заменить target/selector на вариант с замыканием и [weak self]; после этого invalidate не понадобится вовсе
- Проблема в @objc-методе: селектор удерживает контроллер, поэтому tick нужно сделать статическим
