Lazy properties

If you have a property that might take some time to calculate, you don’t want to slow things down until you actually need the property. Say hello to the lazy stored property. This could be useful for such things as downloading a user’s profile picture or making a serious calculation.

Look at this example of a Circle structure that uses pi in its circumference calculation:

struct Circle { lazy var pi = {

return ((4.0 atan(1.0 / 5.0)) - atan(1.0 / 239.0)) 4.0

}()

var radius = 0.0

var circumference: Double { mutating get {

return pi radius 2

}

}

init (radius: Double) { self.radius = radius

}

}

Here, you’re not trusting the value of pi available to you from the standard library; you want to calculate it yourself.

You can create a new Circle with its initializer, and the pi calculation won’t run yet:

var circle = Circle(radius: 5) // got a circle, pi has not been run

The calculation of pi waits patiently until you need it. Only when you ask for the circumference property is pi calculated and assigned a value:

let circumference = circle.circumference // 31.42

// also, pi now has a value

Since you’ve got eagle eyes, you’ve noticed that pi uses a { }() pattern to calculate its value, even though it’s a stored property. The trailing parentheses execute the code inside the closure curly braces immediately. But since pi is marked as lazy, this calculation is postponed until the first time you access the property.

For comparison, circumference is a computed property and therefore gets calculated every time it’s accessed. You expect the circumference’s value to change if the radius changes. pi, as a lazy stored property, only gets calculated the first time. That’s great, because who wants to calculate the same thing over and over again?

The lazy property must be a variable, defined with var, instead of a constant defined with let. When you first initialize the structure, the property effectively has no value. Then when some part of your code requests the property, its value will be calculated. So even though the value only changes once, you still use var.

As another consequence of the value changing, the getter must be marked as mutating since it changes the value of the structure. You’ll learn more about mutating in the next chapter, Methods.

Note: Of course, you should absolutely trust the value of pi from the standard library. It’s a type property and you can access it as Double.pi.

results matching ""

    No results matching ""