AntiMoron
AntiMoron

Reputation: 1366

What's the purpose of initializing property values before calling super designated initializer in swift?

Here is my code:

class Base
{
    init(){
        print("Super!")
    }
}

class Test : Base
{
    internal var y:Int
    convenience init(_ a:Int)
    {
        self.init()
        print("\(a)")
    }
    override init()
    {
        super.init() //Error!!! Property 'self.y' not initialized at super.init call
        y = 123
    }
}

I think this should be compiled:

y is not visible inside class 'Base',whether order of initializations of y's and super class's doesn't really matter.

Upvotes: 7

Views: 779

Answers (2)

Martin R
Martin R

Reputation: 539835

Your argument

I think this should be compiled:

y is not visible inside class 'Base',whether order of initializations of y's and super class's doesn't really matter.

is not correct, that would not be safe.

The superclass init can call an instance method which is overridden in the subclass. That is (at least one) reason why all subclass properties must be initialized before super.init() is called.

A simple example:

class Base
{
    init(){
        print("enter Base.init")
        setup()
        print("leave Base.init")
    }

    func setup() {
        print("Base.setup called")
    }
}

class Test : Base
{
    internal var y:Int
    override init()
    {
        y = 123
        print("before super.init")
        super.init()
        print("after super.init")
    }

    override func setup() {
        print("Test.setup called")
        print("y = \(y)")
    }
}

Output:

before super.init
enter Base.init
Test.setup called
y = 123
leave Base.init
after super.init

As you can see, the y property of the subclass is accessed during the super.init() call, even if it is not known to the superclass.


It might be interesting to compare the situation in Objective-C where self = [super initXXX] is always called first. This has the consequence that property access self.prop in init/dealloc methods is unsafe and direct access to the instance variable _prop is recommended because the object may be in a "partially constructed state". See for example Should I refer to self.property in the init method with ARC?.

So this is one of the issues which have been solved in Swift (at the cost of stricter requirements).

Upvotes: 11

vadian
vadian

Reputation: 285082

From the documentation:

Safety check 1
A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.

As mentioned above, the memory for an object is only considered fully initialized once the initial state of all of its stored properties is known. In order for this rule to be satisfied, a designated initializer must make sure that all its own properties are initialized before it hands off up the chain.

Source: Swift Language Guide: Initialization

Just exchange the two lines in init

override init()
{
    y = 123
    super.init()  
}

Upvotes: 3

Related Questions