Deinit Never Called

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



Leave a reply



Submit