I\'m creating a ViewController object an pushing it to a navigation controller. When the object is being popped from the stack - it is not being release and Deinit is not be
I faced the same Problem. In my case a never ending cycle of UIView.animateWithDuration... holds the ViewController in Memory and blocks the call of deinit. If you use something like this you have to stop it first bevor you remove the ViewController. Hope that helps.
I had similar problem. I added empty deinit
method to my class and added breakpoint:
deinit {
}
As result it's never called.
As soon as I add some code to the body it started working as expected:
deinit {
print("deinit called")
}
So be sure that your deinit
method isn't empty.
PS. I am using Swift 2, Xcode 7.1
I just ran into a similar issue. My problem appears to have been caused by a strong reference to a control that had delegate assignment not specified as 'weak' with a class type protocol.
I had the same issue when the NotificationCenter was holding a strong reference to the presented view controlled and thus it was never getting released. So I had to add [weak self] to the block like this:
(in the viewDidLoad)
NotificationCenter.default.addObserver(forName: .showFoo, object: nil,
queue: OperationQueue.main) { [weak self] (notification) in
if let foo = notification.userInfo?["foo"] as? Foo {
self?.afooButton!.setImage(UIImage(named: "foo"), for: .normal)
}
}
I had a timer in my view controller, running every minute to update a label. I put a call in deinit to invalidate the timer, which I'm pretty sure is what I've always done in Objective-C (in dealloc) and it's worked. But it seems a little different in Swift so I moved the time creation/invalidation code to viewWillAppear/viewWillDisappear (which makes more sense really) and everything seems fine now!
Do any of your classes, or properties they contain make a reference to the view controller you've popped?
If your UIViewController has created an instance of an object, which in turn makes a 'strong' reference to that view controller (e.g. a reference that's not explicitly declared 'weak' or 'unowned'), and your view controller keeps a strong reference to that object as well, neither will be deallocated. That's called a strong reference cycle, documented here (a must read for serious Swift developers):
The Swift Programming Language (Swift 3.0.1): Automatic Reference Counting
Closures are a more insidious case where you can get into trouble.
One thing you might try as an experiment is pushing the controller and popping it before you do anything in viewDidLoad or in the initialization, and see if the deinit method is being called. If it is, then you should be able to incrementally discover what you're doing that's leading to the symptom you're seeing.
Another thing that can thwart diagnosis (as other answers have pointed out), which I learned the hard way, is that the debugger breakpoint won't be taken for deinit() if the deinit method contains no executable statements, because the OS or compiler optimizes the deinit invocation away if it's empty, so at least put a print statement there if you want to verify deinit() is getting called.