Property getters and setters
Setters and Getters apply to computed properties
; such properties do not have storage in the instance - the value from the getter is meant to be computed from other instance properties. In your case, there is no x
to be assigned.
Explicitly: "How can I do this without explicit backing ivars". You can't - you'll need something to backup the computed property. Try this:
class Point {
private var _x: Int = 0 // _x -> backingX
var x: Int {
set { _x = 2 * newValue }
get { return _x / 2 }
}
}
Specifically, in the Swift REPL:
15> var pt = Point()
pt: Point = {
_x = 0
}
16> pt.x = 10
17> pt
$R3: Point = {
_x = 20
}
18> pt.x
$R4: Int = 10
You can customize the set value using property observer. To do this use 'didSet' instead of 'set'.
class Point {
var x: Int {
didSet {
x = x * 2
}
}
...
As for getter ...
class Point {
var doubleX: Int {
get {
return x / 2
}
}
...
Setters/getters in Swift are quite different than ObjC. The property becomes a computed property which means it does not have a backing variable such as _x
as it would in ObjC.
In the solution code below you can see the xTimesTwo
does not store anything, but simply computes the result from x
.
See Official docs on computed properties.
The functionality you want might also be Property Observers.
What you need is:
var x: Int
var xTimesTwo: Int {
set {
x = newValue / 2
}
get {
return x * 2
}
}
You can modify other properties within the setter/getters, which is what they are meant for.
To elaborate on GoZoner's answer:
Your real issue here is that you are recursively calling your getter.
var x:Int
{
set
{
x = newValue * 2 // This isn't a problem
}
get {
return x / 2 // Here is your real issue, you are recursively calling
// your x property's getter
}
}
Like the code comment suggests above, you are infinitely calling the x property's getter, which will continue to execute until you get a EXC_BAD_ACCESS code (you can see the spinner in the bottom right corner of your Xcode's playground environment).
Consider the example from the Swift documentation:
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
Notice how the center computed property never modifies or returns itself in the variable's declaration.