Jim Kubicek

Octo-Impressive

Don’t Lazily Load Your Views

I seem to run accross a lot of developers lazily loading their properties. As an example:

- (UILabel *)myTextLabel {
     if (_myTextLabel == nil) {
         _myTextLabel = [[UILabel alloc] init];
         [self addSubview:_myTextLabel];
     }
 }

At least in iOS developement, I suspect this is caused by Apple’s sample code, particularly Apple’s default setup for Core Data projects. There are some valid reasons why you’d want to lazily load a resources, but there’s lots of great reasons why you shouldn’t. Here’s a few:

Property calls should not have side effects

There are lots of exceptions for setters (like updating the UI after setting a property), but there are very few exceptions for getters. You shouldn’t need to worry about your object changing state when you access a property.

Lazy loading is confusing

self.myTextLabel = nil;
if (self.myTextLabel) {
 NSLog(@"What the shit? How did I get here?");
}

Lazy loading leads to tricky initialization order dependences

- (UILabel *)myTextLabel {
    if (_myTextLabel == nil) {
        _myTextLabel = [[UILabel alloc] init];
        _myTextLabel.text = self.myTitle;
        [_myTextLabel sizeToFit];
        [self addSubview:_myTextLabel];
    }
}

Now your label will have different text depending on whether you set myTitle before or after you access myTextLabel.

Lazy loading leads weird code

Like this:

if(self.myTextLabel) // just need to setup my text label

Initialization, layout, UI updates should be localized

You should be performing all initialization in the init method, UI updates in an update UI method and layout in layoutSubviews. Not only does this make debugging far easier (having layout issues? I feel bad for you, son. I’ve got 99 problems, but performing view layout anywhere other than layoutSubviews isn’t one.), but it ensures that your view is always in a consistent state. Big Nerd Ranch has a great writeup on why this is important.

Clearly there are exceptions to all these rules and situations where lazily loading your view properties is the right thing to do. But remember, always write code that emphasizes clarity first and optimize for speed or memory constraints later.

Comments