Search code examples
iosswiftuinavigationcontrollerswift3nstimer

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.


Solution

  • 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).