21

I have a very simple class

class SimpleClass {
    var simpleDescription: String {
    get {
        return self.simpleDescription
    }
    set {
        self.simpleDescription = newValue
    }
    }
}

What is the correct way to define a default value for the simpleDescription variable?

jscs
  • 63,694
  • 13
  • 151
  • 195
JuJoDi
  • 14,627
  • 23
  • 80
  • 126

4 Answers4

25

In Swift, getters and setters are used for computed properties - there is no storage for the property and thus, in your case, simpleDescription can't be set in a setter.

If you need a default value, use:

class SimpleClass {
  var simpleDescription: String = "default description"
}

if you want to initialize use:

class SimpleClass {
  var simpleDescription: String
  init (desc: String) {
    simpleDescription = desc
  }
}
jscs
  • 63,694
  • 13
  • 151
  • 195
GoZoner
  • 67,920
  • 20
  • 95
  • 145
17

If what you want is to perform an action each time a variable is set or just to check if the value is correct you can use Property Observers
From docs:

Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value.

You can use them like this:

class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

EDIT

Looks like this doesn't work when overriding inherited properties. Here is an example of what you can't do:

class StepWihtoutCounter {
    var totalSteps: Int = 0 
}

class StepCounter: StepWihtoutCounter {
    override var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
Mark E
  • 3,403
  • 2
  • 22
  • 36
  • This doesn't work for me, as I'm still getting the same error as the question above asked about. Using Xcode 7.3 beta 5 7D152p. – hhanesand Mar 08 '16 at 01:16
  • Can't find any error described in the original question, it only asks how to do it. Which is your error? – Mark E Mar 08 '16 at 01:20
  • Results in compile error : `Variable with getter/setter cannot have an initial value`. I landed here via google search, so I just assumed that the poster had the same error as me and did not bother reading question. :) I may be running into issues because this is an `override`, however.... – hhanesand Mar 08 '16 at 01:27
  • Just tested on playground, it looks like the problem is that you can't use property observers on `override`n properties. A quick search led me to this http://stackoverflow.com/questions/29503482/override-property-observer which suggest creating a placeholder function which is called from the original didSet in the parent class so you only override that function – Mark E Mar 08 '16 at 01:40
  • @hhanesand Edited, added your case for clarity when someone stumbles upon this – Mark E Mar 08 '16 at 16:33
3

The solution is easy. Just use another variable, get it back in getter.

var _simpleDescription = "Default value"

var simpleDescription: String {
    get {
        return self._simpleDescription
    }
    set {
        self.simpleDescription = newValue
    }
}
Boomerange
  • 616
  • 1
  • 10
  • 18
1

Setting a simple value directly:

var string1: String = "value" {
    willSet {
        print("willSet")
    }
    didSet {
        print("didSet")
    }
}

Setting the result of a computed closure:

var string2: String = {
        let value = "value"
        return value
    }() {
    willSet {
        print("willSet")
    }
    didSet {
        print("didSet")
    }
}
pkamb
  • 33,281
  • 23
  • 160
  • 191