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
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
}
}
}
get and set are for computed properties (they don't have any backing store). (In my opinion, the keyword 'var' is confusing here)
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)
.
class Shape {
var sideLength: Double {
get {
return self.sideLength
}
set {
// Implement the setter here.
self.sideLength = newValue
}
}
}
Check out perimeter
in this example.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength”
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
}
}