class Animal {
class func generate() -> Animal {
return self()
}
}
The compiler complains constructing an object of class type 'Animal' with a metatype value must use a 'required' initializer
I can understand this. If I write a subclass like this:
class SubAnimal: Animal {
let head: Int
init(head: Int) {
self.head = head
super.init()
}
}
It will inherit Animal
's class method generate()
but won't inherit its default initializer init()
. So SmallAnimal.generate()
actually calls SmallAnimal()
, but SmallAnimal
doesn't have an initializer init()
! Of course this is what the compiler want to prevent.
What confuses me is a similar problem.
class someClass {
}
let anotherClass = someClass.self
let anotherObject = anotherClass()
The compiler still complains constructing an object of class type 'Animal' with a metatype value must use a 'required' initializer.
This time, I cannot understand. anotherClass
is a metatype value, but what bad result will be caused?
I know how to solve this problem, adding required init() {}
is the solution. But I really want to know the reason for the second case.
Consider the case where we also have a subclass:
class SomeClass {
}
class SomeSubclass : SomeClass {
}
If you store the class type in a variable:
var anotherClass = SomeClass.self
The variable anotherClass
is of type SomeClass.Type
.
You can later assign this variable to a subclass:
anotherClass = SomeSubclass.self
This is valid because SomeSubclass.Type
is a SomeClass.Type
. At this point, anotherClass()
would fail if the initializer is not implemented in the subclass. This is what the compiler is protecting against.
In your sample code, this is impossible: you used let
instead of var
so changing the type is impossible. It may be that the safety checks just aren't nuanced enough to notice this.
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