From the very first time that i encountered lazy keyword and lazy initialisation in my iOS Dev career, i was kind of interested in the concept. It never made much sense to me in the beginning why would we even use lazy keyword in the first place as all it does is , sort of, postpone initialisation of your object/variable or whatever you’re declaring lazy as up until it is called the first time .
From Swift Documentation :
A lazy stored property is a property whose initial value is not calculated until the first time it is used
Alright. Alright. You must have read this line many times before and still be wondering “Yeah, i get it . But what would be the ideal case for lazy keyword”
Well , let me start of with an example :
Consider a scenario, where we have a Car that we drive everywhere (duh?) . Be it on a vacation, everyday work, grocery store, a new club that i overheard someone talking about ! Also, let us assume that with the rapid increase in technology, every car has an in-built GPS (though, not every car has one, JUST ASSUME)
Our model is really simple. We have 2 classes for both GPS and Car. Since we have already assumed that every car would have an in-built GPS, class Car has a property gps .
Now, as soon as we reach the line:
We will have the following output on the console :
GPS InitializedCar Initalized
… which , to be honest, is not rocket science !
What it depicts, is that, even when we have only created Car Object, GPS is initialised with it as well .
Let’s say we are travelling to work everyday, local grocery store every week, grandparents house, say, often; In all these cases, we don’t need GPS as we remember the route, even the alternate routes to get there, but with the above code, we will still be allocating memory to GPS variable even when we don’t need it. And we, as programmers, know the value of memory
That’s where lazy comes into picture!
What it does is, it will not be allocated memory until it is called the first time. To make a property lazy, just put the lazy keyword before the var declaration of that property (yup, you read it correct, var, not let as its initial value might not be retrieved until after instance initialization completes)
Now , the output will be :
Car Initalized
See, GPS is not initialised even though we have our Car up and running. Now as soon as we try to access gps property of our myVeryExpensiveCar instance:
and hit run in the playground again, we will see the following added in console :
GPS Initialized
As soon as the compiler saw the lazy keyword, it skipped the initialisation and didn’t allocate memory to that variable. But , as soon as we tried to access the same variable, the first time, it was allocated memory at that very moment and after this point, it can be used a normal variable
Now you might be wondering: if lazy is so good, why don’t we default all our variables to lazy? There are 2 reasons that i can think of right now
lazy variables are always declared var , so, one can never create immutable variables .
The internals of lazy requires a branch, to check if there’s a value already present, or if it’s necessary to compute one for the first time, which adds overhead and thus outweighs the benefit of lazy. Let me explain this one
A simple lazy variable declaration look like this :
However, the way it works under the hood is something like this :
....... this if-else is the branching I was talking about; which adds overhead!
Finally, the million dollar question, when are lazy variable needed in real programming world ?
They are useful when the initial value for a property requires complex calculations that should not be performed unless or until it is really needed.(Just like our GPS, you know how complex computation a GPS requires, me neither 😅)