Lazy instantiation in Objective-C/ iPhone development

user1452574 picture user1452574 · Aug 2, 2012 · Viewed 23.3k times · Source

Quick question... Well I understand that all properties start out as nil in Objective-C and that sending a message to nil does nothing, therefore you must initialize using [[Class alloc] init]; before sending a message to a newly created property. However, what about if I'm not sending messages to this property or if I set the property using self.property = something? Do I need to alloc init in these cases as well? Also, do UI properties start out as nil as well, such as a UILabel property that you drag out from your storyboard? Do these need alloc init?

Thanks to all who answer

Answer

Jason C. Howlin picture Jason C. Howlin · Aug 2, 2012

Stunner did a good job of explaining not needing to alloc init objects that have already been created.

But if it is an object that doesn't exist, where are you going to create it? A very common pattern, which I mention because you mentioned it in your post, is lazy instantiation.

So you want an NSMutableArray property. You could alloc init it in some method before you use it, but then you have to worry about "does that method get called before I need my array?" or "am I going to call it again accidentally and re-initialize it."

So a failsafe place to do it is in the property's getter. It gets called every time you access the property.

.h
@property (nonatomic, strong) NSMutableArray* myArray;

.m
@synthesize myArray = _myArray;

- (NSMutableArray*)myArray
{
    if (!_myArray) {
        _myArray = [[NSMutableArray alloc] initWithCapacity:2];
    }
    return _myArray;
}

Every time you access that property, it says, "Does myArray exist? If not, create it. If it does, just return what I have."

Plus an added benefit with this design pattern is you aren't creating resources until you need them, versus creating them all at once, say, when your view controller loads or your app launches, which, depending on the requirements, could take a couple seconds.