Swift Lazy Vars Explained
What are lazy vars, what do they do. Lazy sounds like a bad thing right? Lets first take a look at how variables work to then understand the benefits of lazy vars.
What are lazy vars?
When you declare a variable in Swift it takes up memory and also takes time to set the variable (Although it is quite quick)
Lets run through an example, each time we set a variable it takes up memory.
var name: String = “Hello”
var age: Int = 2
var players: [String] = [“Bob”, “Troy”, “Fay”]
As we know – there is actually a LOT of memory for these variables (For most of the coding you do). The memory usage would be more akin to this:
So how do lazy variables work?
First we declare the variable, it doesn’t actually load up straight away or take any memory.
lazy var lazyName: String = {
return “John”
}()
Now if we use the variable later. It loads itself into memory as follows. Also it only loads itself once into memory which is the first time you use it.
print(lazyName)
Using lazy vars in Swift
Let’s create a new single page viewController app in Swift, and go to the ViewController.swift to look at implementing lazy vars:
Under class ViewController: UIViewController add the following variables and lazy vars.
var name = "Bobby" lazy var lazyName: String = { return "John" }() var age: Int? lazy var lazyAgeIntro: String = { return "The age is \(self.age!)" }()
Then in viewDidLoad lets set the age variable and print out the variables:
age = 22 print(name) print(lazyName) print(lazyAgeIntro)
Run the app and we see the output in the console works:
Bobby John The age is 22
Note the following:
- A lazy var needs to be strongly typed (In this case lazyName is a String
- You will notice in the above code the lazyAgoIntro allows us to use a variable inside, which is useful if you don’t know what the value will be at run time
- You can run functions such as addition, any other code you could usually write inside lazy vars
- A lazy var needs to be declared in the following format, which looks similar to a function
lazy var varibleName: varibleType = {
return something
}()
So why would we use them, lets look at an example:
- You might have an array with 1 million soccer players that is loaded from a local database
- If you use a variable to load it as soon as your app loads it takes 4 seconds to set which results in a bad user experience
- You can use a lazy var to load it up only when it is actually used. This frees up resources for your app to load resulting in a better use experience
The memory test!
So how do we actually check that lazy vars don’t take up memory until they are used? We can simply use the debugger and inspect the memory. Set a breakpoint just before the print(name) line:
Then run the code – you will see that execution stops at the breakpoint
See that the lazyName.storage and lazyAgeIntro.storage is nil? This means it hasn’t been used yet so there’s nothing there.
Use the step over button to run the next lines of code one at a time. You will notice that when we print out lazyName and lazyAgeIntro they get initialized and loaded into memory.