Reputation: 25280
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")
}
}
Upvotes: 2
Views: 247
Reputation: 11210
As @matt says, you have problem with retain cycle. You can avoid it using Timer
with block where you can declare weak
reference for self
timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { [weak self] timer in
guard let self = self else {
timer.invalidate()
return
}
print("updating progress")
}
You also don't need deinit
in this case since you're invalidating timer inside guard
's else
block and you also don't need variable timer
and you can just write Timer
if you don't want to invalidate timer manually somewhere else
override func viewDidLoad() {
super.viewDidLoad()
Timer.scheduledTimer(...) { ... }
}
Upvotes: 1
Reputation: 536027
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.
Upvotes: 3