【问题标题】:Swift subclass versus protocolSwift 子类与协议
【发布时间】:2017-10-12 12:13:38
【问题描述】:

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

如果我的 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”,则该代码将起作用。 任何人都可以向我解释这一点吗? 谢谢

【问题讨论】:

    标签: ios swift protocols


    【解决方案1】:

    由于协议与具有 reference 语义的类相关,请添加 class 属性

    protocol SettingsOptionsTable : class {
    

    否则协议将被视为具有 value 语义的对象并导致错误。

    来自文档:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      相关资源
      最近更新 更多