这是一个简单的协议:
protocol StringsInitiable {
init(strings: [String])
}
在对NSObject约束时,尝试在扩展中使用初始化程序...
extension StringsInitiable where Self: NSObject {
func test() {
let _ = Self(strings: [])
}
}
...但不是在对UIViewController的约束时。然后它抱怨初始化程序应标记为“编码器”,参考NSCoding的强制初始化程序。
extension StringsInitiable where Self: UIViewController {
func test() {
let _ = Self(strings: []) // error label 'strings:' expected 'coder:'
}
}
有没有办法使用协议中声明的初始化程序,即使是UIViewController子类?
修改
在将扩展限制为基类(NSObject或任何不从任何东西继承的Swift类)时似乎正在工作,但在将扩展限制为子类时却没有。
答案 0 :(得分:2)
我并不完全相信,但这闻起来像个臭虫。看看这个没有编译的例子:
protocol P {
init(n: Int)
}
class A {}
class B : A {}
extension P where Self : B {
func f() -> Self {
return Self(n: 3) // Error
}
}
但这会编译:
extension P where Self : A {
func f() -> Self {
return Self(n: 3)
}
}
可能你不想要一个协议,因为你甚至将其命名为StringsViewController
。您可能应该继承UIViewController
:
class StringsViewController : UIViewController {
convenience init(strings: [String]) {
self.init()
}
}
extension StringsViewController {
func test() {
let _ = StringsViewController(strings: [])
}
}
或者如果你真的想要一个协议,你可以这样做:
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)
}
}
答案 1 :(得分:0)
UIViewController没有这样的初始化器,因为你还没有实现StringsViewController协议。您将无法为UIViewController实现此协议,因为您无法将设计的初始化程序声明为扩展。另一方面,您需要一个指定的初始化程序,以符合协议的初始化要求。