Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deinit / Invalidate Timer

I'm trying to deinit/invalidate Timer when user press back button but not when he push to next 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()
    }
}

It is not working when user press back button.

like image 580
Nitesh Avatar asked Feb 03 '17 03:02

Nitesh


2 Answers

When you use a scheduled timer with 'target/selector', it retains its target. More specifically, the Runloop retains scheduled timers, in turn which retain their target.

I use this version, which doesn't retain self:

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

And you'll still need to invalidate the above timer in your deinit as well, otherwise you'll leak the timer (but not your class).

like image 75
Chris Avatar answered Nov 13 '22 04:11

Chris


Don't put the timer invalidate in viewWillDisappear(_:). Create a deinit method and put it there. When you press the back button the current view controller should be released and the deinit method will fire.

deinit {
  timer.invalidate()
}
like image 4
Duncan C Avatar answered Nov 13 '22 05:11

Duncan C