Swift: Why does a variable with a setter must also have a getter? Swift: Why does a variable with a setter must also have a getter? swift swift

Swift: Why does a variable with a setter must also have a getter?


Quick answer for the quick question "Why?":

Once you add a get (or set) to a property, it turns into a Computed Property. Computed properties may be read-only, thus requiring only a getter, but they may not be write-only. So if you add a setter to a property, you turn it into a computer property hence you must add a getter as well.

EDIT: Following comments, Why can Computed Properties be read-only, but not write-only?

I can't find official documentation to back this up, so the following explanation is solely based on my logical point of view:

Computed Properties don't store actual data on their variables; instead they compute data to display.

var a:Int = 5 // Stored propertyvar timesTen:Int { // Computed Property    get {        return a * 10    }}

From the example above: a is a Stored property. Therefore, its get method automatically returns a's value. Now think of timesTen: What's its value? Since it doesn't store any value in timesTen variable, you must tell the computed property how and where to read its "value" from. So that's why you can't use a computed property for writing-only purposes.


Workaround / How to avoid it

For simple properties you may use didSet or willSet to achieve the desired purpose:

var proxy: MyProxy?{    willSet { if _proxy == nil && newValue != nil { _proxy = newValue } }}

If you are using Swift 2.x, you may use the guard statement to for a cleaner code:

var proxy: MyProxy?{    willSet {          guard (_proxy == nil && newValue != nil) else { return }         _proxy = newValue    }}

Another observation

If _proxy is not required to be private you may remove it completely, using only one variable/property instead of two:

var proxy: MyProxy!{    willSet {          guard (proxy == nil && newValue != nil) else { return }         // By not preventing `willSet` to continue, `newValue` will automatically assigned to `proxy`    }}


Why cant you just return _proxy in your getter? What does that matter? If you are afraid of exposing your getter you can set your getter to private, thus exposing it only in the containing class.

private(get) var proxy: MyProxy? {  set { if _proxy == nil && newValue != nil { _proxy = newValue } }}


At the moment you can only use property observer didSet or willSet