Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Programming: getter/setter in stored property

Tags:

ios

swift

How do I overwrite the setter of stored property in Swift?

In Obj-C, I can overwrite its setter, but Swift doesn't seem to be happy about getter/setters being used for stored property.

Say I have a Card class with a property called rank. I don't want the client to give it any invalid value, therefore, in objective-C, I can overwrite setRank so that it performs additional check. But willSet in Swift doesn't seem to help because newValue is constant and it makes no sense to assign rank because setter will be called in a loop.

like image 943
bohanl Avatar asked Jun 09 '14 06:06

bohanl


People also ask

Which property will define getter and setter in Swift?

Working With Computed Properties in Swift To create computed properties, Swift offers you a getter and (an optional) setter method to work with. A getter method is used to perform a computation when requested. A setter method is an optional method. It can be used to modify a related property.

What are stored properties in Swift?

Stored Properties A stored property is a property whose value is stored as part of the instance of a particular type. Stored properties can be either variable or constant. We can use var to create a variable stored property, and let to create a constant stored property.

What is willSet and didSet in Swift?

In willSet Swift provides your code with a special value called newValue that contains what the new property value is going to be, and in didSet you are given oldValue to represent the previous value.


4 Answers

Ok. Reading through Apples documentation on Swift I found this:

If you assign a value to a property within its own didSet observer, the new value that you assign will replace the one that was just set.

So all you have to do is this:

var rank: Int = 0 {
    didSet {
        // Say 1000 is not good for you and 999 is the maximum you want to be stored there
        if rank >= 1000  {
            rank = 999
        }
    }
}
like image 158
Mihai Fratu Avatar answered Oct 03 '22 04:10

Mihai Fratu


You can't override get/set for a stored property but you can use property observers willSet/didSet:

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

The default parameter names are newValue for willSet and oldValue for didSet, or you can name them yourself as in willSet(newTotalSteps).

like image 40
Joseph Mark Avatar answered Oct 03 '22 06:10

Joseph Mark


get and set are for computed properties (they don't have any backing store). (In my opinion, the keyword 'var' is confusing here)

  • willSet and didSet are called for an instance variable (Use didSet to override any changes)
  • set and get are purely for computed properties
like image 24
user3675131 Avatar answered Oct 03 '22 06:10

user3675131


If you don't want to use didSet, which has the problem that the property's value is temporarily wrong, you should wrap a computed property around it.

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        if(newValue > 999) {
            _foo = 999
        } else {
            _foo = newValue
        }
    }
}

Or:

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        guard newValue <= 999 else {
            _foo = 999
            return
        }
        _foo = newValue
    }
}
like image 42
Jim Driscoll Avatar answered Oct 03 '22 05:10

Jim Driscoll