How to do proper Lazy Loading in Swift

How lazy are you?


Lazy loading is something every programmer should have in their tool belt, especially when working with smartphone Apps. It will make your apps faster and more memory efficient. Allocation is a slow, so defer it until you need it. Memory is limited, so lets not waste it.

As I see it, you have two options in Swift. I personally prefer the latter one. If I missed something, please fill in the missing bits!

Before I started to code in Cocoa and Objective-C, I usually wrote my C++ code like this. I don’t think this needs any further explanation.

if (variable == NULL) {
variable = new SomeClass()
//Alot of more code
}
this->variable.value = 10;

Moving on to Objective-C and the world of Properties, I took a little different approach.

- (SomeClass*)variable {
if (_variable == nil)
_variable = [[SomeClass alloc] init];
return _variable;
}
- (void)someMethod {
self.variable.value = 10;
}

So how do we translate this into Swift? The C# approach.

Ex 1. (not the preferred one)

var _variable:SomeClass?
var variable:SomeClass {
get {
if _variable == nil {
_variable = SomeClass()
}
return _variable!
}
}

This looks a lot like C# without the handy ?? operator though. In this case Swift can do even better, with the @lazy attribute.

Using ‘simple’ lazy without any further customization

Ex 2.

private lazy var variable = SomeClass()

Usage

func someMethod() {
variable.value = 10
}

This is pretty neat, Swift doesn’t allocate variable until we want it just by using the @lazy-attribute. Notice that you can’t use let with @lazy.

But I want to customize the object directly after I allocated it , how do I do that?

Are you ready for some Closure Magic? How to make just that specific instance initialized with value = 10?

private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()

You must use lazy to prevent the closure for being created more than once.

This is ofcourse even more handy when working with graphical elements that you just want to add once with some default property values set.

private lazy var detailLabel:UILabel = {
let label = UILabel()
label.textColor = UIColor.blackColor()
label.font = UIFont(name: “KannadaSangamMN”, size: 14.0)
self.addSubview(label)
return label
}()
Notice that I use let for reference types. If you need to use a structure/value type make sure its an variable. Otherwise you can't change the values of its properties.

There you have it. Lazy loading in Swift!

Follow me on twitter: https://twitter.com/konrad1977

Like what you read? Give Mikael Konradsson a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.