我将表视图嵌入视图控制器中,并尝试从嵌入式表控制器访问父视图控制器保存按钮。如果具有以下协议:

如果我的tableviewcontroller子类(SettingsController)具有saveButton方法并且我使用以下代码,则它可以工作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    super.prepare(for: segue, sender: sender)

    guard let optionsTable = segue.destination as? SettingsController else {
        fatalError("Unexpected destination: \(segue.destination)")
    }

    optionsTable.saveButton = self.saveButton

}

但是,我试图通过协议使用以下实现:
protocol SettingsOptionsTable {

    var saveButton: UIBarButtonItem? {get set}

}

SettingsController正在实现SettingsOptionsTable协议。然而下面的代码:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    super.prepare(for: segue, sender: sender)

     guard let optionsTable = segue.destination as? SettingsOptionsTable else {
         fatalError("Unexpected destination: \(segue.destination)")
     }

     optionsTable.saveButton = self.saveButton

 }

给我一个编译错误:“无法分配给属性:'optionsTable'是一个'let'常量”

我不明白为什么。 optionsTable对象是常量,实现协议,并分配一个属性。
如果我将“guard let”更改为“guard var”,则该代码将起作用。
有人可以向我解释吗?
谢谢

最佳答案

由于协议与具有引用语义的类相关,因此添加class属性

protocol SettingsOptionsTable : class {

否则,该协议将被视为具有值语义的对象,从而导致错误。

从文档中:

当该协议的要求所定义的行为假设或要求符合类型具有引用语义而不是值语义时,请使用仅类协议。

关于ios - Swift子类与协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43950198/

10-10 21:12
查看更多