Reputation: 682
What is the difference between the two lines in Row.swift?
Row.swift
open class Row {
// Existing code (Good):
public var cellIdentifier: String { return String(describing self) }
// The change (Bad):
public var cellIdentifier: String = String(describing: self)
DifferentRow.swift
public class DifferentRow: Row {
public override var cellIdentifier: String { return "\(super.cellIdentifier)" }
// returns the error below
Cannot override mutable property with read-only property 'cellIdentifier'
Upvotes: 0
Views: 765
Reputation: 154711
This:
public var cellIdentifier: String { return String(describing self) }
is defining a computed property. No value is stored. Every time you access cellIdentifier
the closure runs and returns the String
. It is read-only because only the getter has been provided.
This:
public var cellIdentifier: String = String(describing: self)
is a stored value property and it is read/write.
The error is telling you that you can't replace a property that has read/write capabilities with one that has only read capabilities.
Note: if you are initializing a property with a value, you can't access self
because self
doesn't represent the class/struct instance until the object is completely initialized. If you made the property a lazy var
, you could use self
in the initialization, because then the property would be initialized once the first time it is accessed.
You can read more about Swift properties here in the Swift Language Guide
Upvotes: 2
Reputation: 10209
I think the error message is quite confusing.
The problem with
public var cellIdentifier: String = String(describing: self)
is the reference to self
:
cellIdentifier
during definition, self
is not guarateed to be fully initialized.String(describing:)
) and hand-in the half-initilized self
One solution could be to make cellIdentifier
a lazy property:
public lazy var cellIdentifier: String = String(describing: self)
This will automatically delay the function call to the time after initialization has finished.
Upvotes: 0
Reputation: 5358
You can’t override a “read from and write to”-property with a property which one can only read from.
You can assign a different value:
public override var cellIdentifier: String = “newValue”
or create both a set and a get implementation:
public override var cellIdentifier: String {
get { return “\(super.cellIdentifier)” }
set { super.cellIdentifier = newValue }
}
Under Computed Properties
read more on this syntax.
Upvotes: 1