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.
Swift init() Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
A convenience initializer is a secondary initializer that must call a designated initializer of the same class. It is useful when you want to provide default values or other custom setup. A class does not require convenience initializers.
Example: Swift Initializer Inside the initializer, we have initialized the value of the length property. Here, when the wall1 object is created, the init() initializer is called.
Initialization is the process of locating and using the defined values for variable data that is used by a computer program. For example, an operating system or application program is installed with default or user-specified values that determine certain aspects of how the system or program is to function.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With