I'm creating a popover style view controller in storyboard like this
Then I click the button, the view controller shows and when I click anywhere outside, the view controller is "dismissed".
However, when I click the button again, a new instance of the view controller is lunched and the previous one is still running. I have tried deinit
but it's not getting called when the view controller is "dismissed".
How can I either destroy the view controller instance when clicking outside, or "show" the already created instance?
My code in the view controller:
class FileTransViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
timer = Timer.scheduledTimer(timeInterval: 0.25, target: self, selector: #selector(updateProgress), userInfo: nil, repeats: true)
//print(123)
print("\(self)")
}
deinit {
print("destroyed")
if let timer = timer {
timer.invalidate()
}
}
@objc func updateProgress() {
print("updating progress")
}
}
The problem has nothing to do with popovers. You are leaking because you retain the timer while the timer retains you — a classic retain cycle.
To break the cycle, you must invalidate the timer. You cannot do this in deinit
, because by definition it cannot be called until after you break the cycle. NSPopover.willCloseNotification
might be a good opportunity.