这是一个简单的协议(protocol):
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 子类,有没有办法使用协议(protocol)中声明的初始化程序?
编辑
它似乎在将扩展约束到基类(NSObject 或任何不继承任何东西的 Swift 类)时有效,但在将扩展约束到子类时却无效。
最佳答案
我不完全相信,但这闻起来像个错误。看看这个不编译的例子:
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)
}
}
可能您无论如何都不想要一个协议(protocol),因为您甚至将其命名为 StringsViewController
。您可能应该子类化 UIViewController
:
class StringsViewController : UIViewController {
convenience init(strings: [String]) {
self.init()
}
}
extension StringsViewController {
func test() {
let _ = StringsViewController(strings: [])
}
}
或者如果你真的想要一个协议(protocol),你可以这样做:
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)
}
}
关于ios - Swift 协议(protocol)定义了一个不适用于 UIViewController 的 init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38059107/