If you try to create a protocol
in Swift that includes a convenience initialiser
, you will be immediately scolded by the compiler:
protocol Zizo{
convenience init(a:String, b:Int)
}
Convenience initializer not allowed in non class type.
Is there any reason for this limitation? It just doesn't make sense to me.
What could possibly go wrong?
Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. These are known as designated initializers and convenience initializers. Designated initializers are the primary initializers for a class.
The swift compiler will decide which init method to call based on the argument label. Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. Designated initializers are the primary initializers for a class.
Because of this, Swift provides an automatic argument label for every parameter in an initializer if you don’t provide one. The following example defines a structure called Color, with three constant properties called red, green, and blue.
The init (name: String) initializer from the Food class is provided as a designated initializer, because it ensures that all stored properties of a new Food instance are fully initialized. The Food class doesn’t have a superclass, and so the init (name: String) initializer doesn’t need to call super.init () to complete its initialization.
It's because, it makes no sense. protocol
only defines implementers have required methods and properties. It does not define implementation detail. When protocol
requires init(a:String, b:Int)
, you can implement it as either designated or convenience initializer, as you like.
protocol Zizo{
init(a:String, b:Int)
}
class Foo:Zizo {
init() {
}
convenience required init(a:String, b:Int) {
self.init()
}
}
class Bar:Foo {
override convenience init() {
self.init(a:"baz", b:42)
}
required init(a:String, b:Int) {
super.init()
}
}
As you can see, protocol
forces init(a:String, b:Int)
being required
initializer, but does nothing about "convenience" or "designated".
In case you'd still like to do this, you could consider putting a static function in the protocol instead:
protocol Zizo {
static func make(withA a: String, b: Int) -> Self
}
this does get a little hairy when used in a class inheritance tree.
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