Reputation: 25
I am embedding a table view in a view controller and trying to access the parent view controller save button from the embedded table controller. if have the following protocol:
it works if my tableviewcontroller subclass (SettingsController) has a saveButton method and i use the following code:
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
}
however, I am trying to use the following implementation, using a protocol:
protocol SettingsOptionsTable {
var saveButton: UIBarButtonItem? {get set}
}
SettingsController is implementing the SettingsOptionsTable protocol. Yet the code below:
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
}
gives me a compile error:"Cannot assign to property: 'optionsTable' is a 'let' constant"
I don't understand why. The optionsTable object is constant, implements the protocol and I assign a property. The code then works if I change "guard let" to "guard var". Anyone could explain this to me ? thanks
Upvotes: 1
Views: 292
Reputation: 285260
As the protocol is related to a class with reference semantics add the class
attribute
protocol SettingsOptionsTable : class {
Otherwise the protocol is treated as an object with value semantics and that causes the error.
From the documentation:
Use a class-only protocol when the behavior defined by that protocol’s requirements assumes or requires that a conforming type has reference semantics rather than value semantics.
Upvotes: 2