explanation for deinit not called
The usual reason for failure to trigger deinit
when expected is that you have a retain cycle that prevents your view controller from going out of existence.
(Sometimes the reason is that your expectation that the view controller would be destroyed under the circumstances is incorrect. But assuming it is correct, a retain cycle is the reason.)
You mentioned removing all observers. What kind of observers? If we're talking about NSNotification, that is often how you get a retain cycle. The notification center retains the observer until you unregister it. You thus cannot get deinit
until after the observer has been removed. Therefore, you cannot remove the observer in deinit
.
deinit not called in specific case
I expect deinit to be called at program termination
You should not expect that. Objects that exist at program termination are generally not deallocated. Memory cleanup is left to the operating system (which frees all of the program's memory). This is a long-existing optimization in Cocoa to speed up program termination.
deinit
is intended only to release resources (such as freeing memory that is not under ARC). There is no equivalent of a C++ destructor in ObjC or Swift. (C++ and Objective-C++ objects are destroyed during program termination, since this is required by spec.)
ViewController not calling deinit method swift 4
Case 1:
Try writing NotificationCenter.default.removeObserver(self)
line in override func viewWillDisappear(_ animated: Bool)
.
May be notification center retaining you viewController's object.
Case 2:
If you are navigating from you controller using Segue then UIStoryboardSegue
retaining you viewController's object as source viewController.
In that case too first case can solve you issue.
Swift's deinit is not called
You are assigning self
as your table view cell's delegate:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(DBItemCellIdentifier, forIndexPath: indexPath) as! DBItemTableViewCell
let element = elements[indexPath.row]
if let item = element as? DBItem {
cell.configureCellWithItem(item)
} else if let set = element as? DBSet {
cell.configureCellWithSet(set)
}
// HERE
cell.delegate = self
return cell
}
The cell's delegate property is defined as follows:
var delegate: DBItemTableViewCellDelegate?
This creates a strong reference between the cell and the delegate (your view controller). The cell is also retained by the table view. This creates a retain cycle.
You will need to change the definition of the delegate property to be weak
:
weak var delegate: DBItemTableViewCellDelegate?
Edit based on comment:
Your DBItemTableViewCellDelegate
definition will need to be defined as a class-only protocol
protocol DBItemTableViewCellDelegate: class {
...
}
Related Topics
Nsurlsession Concurrent Requests With Alamofire
Photopicker Discovery Error: Error Domain=Pluginkit Code=13
Arkit - What Do the Different Columns in Transform Matrix Represent
Removeobjectsatindexes For Swift Arrays
What Is the 'Open' Keyword in Swift
Non-'@Objc' Method Does Not Satisfy Optional Requirement of '@Objc' Protocol
Initialize @Stateobject With a Parameter in Swiftui
Deleting List Elements from Swiftui'S List
How to Generate a Random Number in a Range (10...20) Using Swift
Call a Method from a String in Swift
Get Integer Value from String in Swift
How to Avoid Force Unwrapping a Variable
Why My Return Is Nil But If I Press the Url in Chrome/Safari, I Can Get Data