Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to override deinit in Swift? [duplicate]

When creating a subclass from another class, it is required to override the init() function, but you cannot override the deinit 'function'.

Is this possible in Swift?

Here is an example

class Foo {
    init(){
        print("Foo created")
    }

    deinit {
        print("Foo gone")
    }
}


class Bar: Foo {

    override init(){
        print("Bar created")
    }

    //Is not overwritten here
    deinit {
        print("Bar gone")
    }
}

Inside example viewcontroller

override func viewDidLoad() {
    super.viewDidLoad()

    var f: Foo?
    f = Foo()
    f = Bar()
    f = nil

}

Output

Foo created    //Foo object initialised - Foo init() called
Foo created    //Foo init() called before calling Bar init()? no call to superclass though..
Bar created    //Bar object initialised - Bar init() called
Foo gone       //Foo deinit called as Foo instance replaced by Bar instance
Bar gone       //Bar deinit called as Bar instance holds no references and is destroyed 
Foo gone       //Foo deinit called again as part of Bar object destruction?

To add to my original question about extending deinit:

In the example code it seems that overriding init() causes a call to the init() function of the superclass. Is this what is happening?

The same behaviour happens when the Bar instance is deinitialised. Is this also what is happening here?

like image 398
Danoram Avatar asked Oct 28 '16 11:10

Danoram


1 Answers

deinit is not a normal method, it cannot be overriden. Every instance has one independent deinit handler for its class and all its superclasses.

Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself. Superclass deinitializers are inherited by their subclasses, and the superclass deinitializer is called automatically at the end of a subclass deinitializer implementation. Superclass deinitializers are always called, even if a subclass does not provide its own deinitializer.

There should be absolutely no reason to change anything the superclass is doing in its deinit.

Why is it different from init? In initializers you need to pass parameters, you also need to control the order of execution (some code before super.init(...), some code after super.init(...)). The deinitialization is an automatic process with a defined order of execution. Overriding could only introduce unnecessary problems.

like image 102
Sulthan Avatar answered Oct 24 '22 17:10

Sulthan