Getter and setter
The computed property you wrote in the previous section is a called a read-only computed property. It comes with a block of code to compute the value of the property. This block of code is called a getter. It’s also possible to create a read- write computed property. Such a property comes with two blocks of code: a getter and a setter. This setter works differently than you might expect. Because the computed property has no place to store a value, the setter usually sets one or more related stored properties indirectly:
var diagonal: Int {
// 1 get {
// 2
let result = sqrt(height height + width width)
let roundedResult = result.rounded(.toNearestOrAwayFromZero) return Int(roundedResult)
}
set {
// 3
let ratioWidth = 16.0 let ratioHeight = 9.0
// 4
height = Double(newValue) * ratioHeight /
sqrt(ratioWidth ratioWidth + ratioHeight ratioHeight) width = height * ratioWidth / ratioHeight
}
}
Here’s what’s happening in this code:
- Because you want to include a setter, you now have to be explicit about which calculations comprise the getter and which the setter, so you surround each code block with curly braces and precede it with either get or set. This isn’t required for read-only computed properties, as their single code block is implicitly a getter.
- You use the same code as before to get the computed value.
- For a setter, you usually have to make some kind of assumption. In this case, you provide a reasonable default value for the screen ratio.
The formulas to calculate a height and width, given a diagonal and a ratio, are a bit deep. You could work them out with a bit of time, but I’ve done the dirty work for you and provided them here. The important parts to focus on are:
The newValue constant lets you use whatever value was passed in during the assignment.
- Remember, the diagonal is an Int, so to use it in a calculation with a Double, you must first transform it into a Double.
- Once you’ve done the calculations, you assign the height and width properties of the TV structure.
Now, in addition to setting the height and width directly, you can set them indirectly by setting the diagonal computed property. When you set this value, your setter will calculate and store the height and width.
Notice that there’s no return statement in a setter — it only modifies the other stored properties. With the setter in place, you have a nice little screen size calculator:
tv.diagonal = 70
let height = tv.height // 34.32... let width = tv.width // 61.01...
Now you can discover the biggest TV that will fit in your cabinet or on your shelf. :]