簡體   English   中英

Swift協議定義的初始化不適用於UIViewController

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM