6

Well I'm just confused when the lazy instantiation should be used. I understand the basic concept of lazy instantiation though.

" 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. "(Lazy instantiation in Objective-C/ iPhone development)

m.file:

@property (strong, nonatomic) NSMutableArray *cards; 

- (NSMutableArray *)cards
{
    if (!_cards) _cards = [[NSMutableArray alloc] init];
    return _cards;
}

- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
    if (atTop) {
        [self.cards insertObject:card atIndex:0];
    } else {
        [self.cards addObject:card];
} }

Well, what I really don't get is when I'm supposed to use this type of instantiation? Mostly I see the code like this:

h.file:

@interface Card : NSObject

@property (strong, nonatomic) NSString *contents;

m.file:

 if([card.contents isEqualToString:self.contents]){
        score = 1;
    }

*This might be a stupid question but I'm really confused. I'm new here, Thanks.

Community
  • 1
  • 1
Toshi
  • 6,012
  • 8
  • 35
  • 58

3 Answers3

2

There is no reason to use Lazy Instantiation/Lazy Initialization if you find it confusing; simply initialize your instance variables/properties in the class init methods and don't worry about it.

As the object is created as a side-effect of calling the getter method, it's not immediately obvious that it is being created at all, so one alternative, which would also mean you can use the default compiler-generate getter method, is to explicitly check for it in addCard:

- (void)addCard:(Card *)card
          atTop:(BOOL)atTop
{
    if (!self.cards)
        self.cards = [NSMutableArray new];

    if (atTop) {
        [self.cards insertObject:card atIndex:0];
    } else {
        [self.cards addObject:card];
    }
}

(and removing the user-supplied getter method)

However the net-effect is the same as the code you posted, with the exception that self.cards will return nil until addCard is called, however I doubt this will cause a problem.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
1

When using dot notation to access your instance variables, you are calling your getter method for that given property. Therefore, by using dot notation and lazy instantiation, your getter will always assert that a property is not nil before you send it a message. Therefore, code such as

[self.cards insertObject:card atIndex:0];

will actually call the getter at self.cards; if you use dot notation on your objects and program the getters accordingly, you will always ensure that your instance variables are allocated and initialized, while simultaneously cleaning up your init method for code that is much more important.

Lazy instantiation is a common practice among Objective-C programmers; I suggest getting into the flow of the convention.

EDIT: thanks for Raphael mentioning this in a comment previously.

sammoore
  • 330
  • 1
  • 10
  • Why only dot notation? – Mick MacCallum Feb 19 '14 at 23:15
  • 1
    This is very late; anyway, using underscore notation will directly access the memory of the object and allow you to make chances that way; on the other hand, dot notation will access the getters and setters methods instead, allowing you to run code every time the notation is used (i.e. making sure the ivar in question is not nil (and setting it up if it is), and making sure whatever someone is attempting to set for a given ivar is valid. – sammoore Dec 17 '14 at 21:24
0

Lazy instantiation is a performance enhancement in certain types of scenarios. One example would be a class that has a very expensive user facing UI string. If you create many of instances of that class but only a very small subset of those instances will be shown in your UI, you waste a lot of CPU resources creating a very expensive UI string that rarely will be used.

Mojo66
  • 1,109
  • 12
  • 21