我在视图控制器中嵌入了一个表视图,并尝试从嵌入式表控制器访问父视图控制器保存按钮。如果有以下协议:
如果我的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”,则代码可以正常工作。 有人可以向我解释一下吗? 感谢
答案 0 :(得分:2)
由于协议与具有引用语义的类相关,因此添加class
属性
protocol SettingsOptionsTable : class {
否则,协议将被视为具有 value 语义的对象,并导致错误。
来自文档:
当该协议的要求定义的行为假定或要求符合类型具有引用语义而不是值语义时,使用仅类协议。