Reputation: 601
Here is a simple protocol:
protocol StringsInitiable {
init(strings: [String])
}
Trying to use the initializer in an extension works when constraint to NSObject...
extension StringsInitiable where Self: NSObject {
func test() {
let _ = Self(strings: [])
}
}
...but not when constraint to UIViewController. It then complains that the initializer should be labeled 'coder', referring to the mandatory initializer from NSCoding.
extension StringsInitiable where Self: UIViewController {
func test() {
let _ = Self(strings: []) // error label 'strings:' expected 'coder:'
}
}
Is there a way to use the initializer declared in the protocol even when being a UIViewController subclass?
EDIT
It seems to be working when constraining the extension to a base class (NSObject or any Swift class that doesn't inherit from anything) but not when constraining the extension to a child class.
Upvotes: 1
Views: 608
Reputation: 14983
I'm not entirely convinced, but this smells like a bug. Have a look at this example which doesn't compile:
protocol P {
init(n: Int)
}
class A {}
class B : A {}
extension P where Self : B {
func f() -> Self {
return Self(n: 3) // Error
}
}
But this compiles:
extension P where Self : A {
func f() -> Self {
return Self(n: 3)
}
}
Probably you don't want a protocol for that anyways, since you even named it StringsViewController
. You should probably subclass UIViewController
:
class StringsViewController : UIViewController {
convenience init(strings: [String]) {
self.init()
}
}
extension StringsViewController {
func test() {
let _ = StringsViewController(strings: [])
}
}
Or if you really want a protocol you can do something like this:
protocol HasView {
var view : UIView! { get }
}
protocol StringsInitable {
init(strings: [String])
}
extension UIViewController : HasView {}
extension HasView where Self : StringsInitable {
func test() {
let n = Self(strings: [])
print(n.view)
}
}
Upvotes: 2
Reputation: 445
UIViewController doesn't have such an initialiser, because you haven't implemented the StringsViewController protocol. You would not be able to implement this protocol for UIViewController, because you cannot declare a designed initialiser into an extension. On the other hand you need a designated initialiser in order to conform to a init requirement of a protocol.
Upvotes: 0