[英]Swift protocol defines an init that doesn't work for UIViewController
這是一個簡單的協議:
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類)時,這似乎是可行的,但當將擴展限制為子類時,則無效。
我並不完全相信,但這聞起來像個蟲子。 看一下這個沒有編譯的例子:
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)
}
}
UIViewController沒有這樣的初始化程序,因為您尚未實現StringsViewController協議。 您將無法為UIViewController實現此協議,因為您無法在擴展中聲明設計的初始化程序。 另一方面,您需要指定的初始化程序才能符合協議的初始化要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.