Swift: How To Be Lazy

As an Objective-C developer, I use lazy loading of my properties whenever possible. Lazy loading is initializing your properties only if / when they are called. This way, memory is not allocated for that property until absolutely necessary, and if the property is actually never used, the memory doesn’t get allocated at all.

If you’re not familiar with lazy loading in Objective-C, it looks like this:

#import "HomerSimpson.h"

@interface HomerSimpson()

@property (strong, nonatomic) NSNumber *beersPerDay;

@end

@implementation HomerSimpson

- (NSString *)homersDrinkHabit
{
    return [NSString stringWithFormat:
            @"Homer Simpson drinks %@ beers per day!",
            self.beersPerDay];
}

#pragma mark - Getter / Setter Overrides

- (NSNumber *)beersPerDay
{
    if (!_beersPerDay) {
        self.beersPerDay = @17;
    }
    return _beersPerDay;
}

@end

The beersPerDay property only gets set to the number 17 only if / when the homersDrinkHabit method is called.

The same code in Swift looks like this:

class HomerSimpson {

    lazy var beersPerDay = 17

    func homersDrinkHabit() -> String {
        return "Homer will drink \(beersPerDay) beers today"
    }

}

That’s it! The lazy keyword makes sure the property is only set if / when it’s called. Note that lazy properties have to be vars.

But what if you have more logic to setting your variable? No problem! In Swift, you can use a closure to do any logic you like when the variable gets set:

lazy var beersPerDay: Int = {

        var dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "EEEE"
        let dayOfWeek = dateFormatter.stringFromDate(NSDate.date())

        if dayOfWeek == "Saturday" || dayOfWeek == "Sunday" {
            return 30
        } else {
            return 17
        }
    }()

In a lazy property, the closure will only get calculated on the first time the property gets called.

As you can see, using lazy loading is easier than ever in Swift. Use it whenever possible, since it’ll save memory and make your code more efficient.

Enjoy being lazy!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Marc Schillhorst

    Hi thank you for the Tutorial:-)
    I have one question.
    You say this is a closure. What is the difference between a closure and a computed propertie? This looks for me the same (in this case)
    Thank you

    Marc

    • A closure is an anonymous function. A computer property is created by coupling it with a closure – a function that is executed every time property is called. To execute a closure, the syntax is {// your function here}(). Hope that makes sense!

      • MarcS

        Thank you Natasha:-)

    • Also, in case you haven’t see it, I wrote a blog post on computed properties so you can compare: http://natashatherobot.com/swift-computed-properties/.

      In a computed property, you’re passing in a closure that is re-executed every time the property is called, whereas in lazy properties, you’re assigning the result of the closure that is only calculated once to the property.

      • cloud

        Do you mean that the properties inside the lazy closure are not computer second time if i initialise the same property?
        like
        first intialisation:- foo.beersperday-> inside the closure the properties are computed on first call
        second intitialsation:- foo.beersperday-> here only the result is return,i.e no properties inside the lazy gets executed?

  • joey

    I’ve noticed if you set the lazy var to nil (after changing its type to optional), if you try to access it again the app crashes – it won’t lazily instantiate again. Do you know how to obtain true lazy instantiation?

  • Pavel Gnatyuk

    I’d mention that the lazy property is initialized when it’s first time called and never changed. Am I right?