Moose
Moose

Reputation: 1317

Lazy Instantiation in the View Controller

I have a button that triggers a random sound from an array in a class. I have lazy instantiation in my view controller that is triggered by an IBAction, but I feel this is incorrect because of two reasons:

1) I usually see people doing L.I. in getters and setters.

When I try to do the L.I. in the getter/setter, my program crashes and I don't know why.

2) I am performing this lazy instantiation inside of the view controller IBAction.

Is this a correct way to do Lazy Instantiation?

here is the code that does not crash:

- (IBAction)myClass:(UIButton *)sender
{

    if (!self.myClass){
        self.myClass = [[myClass alloc] init];
        [self.myClass setUpMyClass]; // this method just loads sounds and some text
    }


    [self.myClass playSound];
    self.myClassLabel.text = [[NSString alloc] initWithFormat:@"%@", [self.myClass someText]];

}

here is the code that crashes:

- (myClass *)myClass
{

    if (!self.myClass){
        self.myClass = [[myClass alloc] init];
        [self.myClass setUpMyClass]; // this method just loads sounds and some text
    }

    return self.myClass;
}

- (IBAction)myClass:(UIButton *)sender
{
    [self.myClass playSound];
    self.myClassLabel.text = [[NSString alloc] initWithFormat:@"%@", [self.myClass someText]];

}

The out put in the debugger doesn't say much but there is a green arrow next to the line that says

-(myClass *) myClass {

and it says

Thread 1: EXC_BAD_ACCESS (code=2, address =0xbf7ffffc)

for user named aqua, the method setUpMyMethod looks like this:

-(void) setUpEscha{
    self.eschaDialogue = [[NSArray alloc] initWithObjects:
                       [[NSBundle mainBundle] pathForResource:@"Sound1" ofType:@"mp3"],
                       [[NSBundle mainBundle] pathForResource:@"Sound1" ofType:@"mp3"],
                       ...
                       nil];

self.eschaLines = [[NSArray alloc] initWithObjects:
                    @"String1",
                    @"String2",
                    @"...",
                    nil];

}

Upvotes: 3

Views: 861

Answers (1)

XJones
XJones

Reputation: 21967

Your getter is calling itself recursively. Don't access self.myClass within the myClass getter. Change your code to:

- (myClass *)myClass
{
    if (!_myClass){
        _myClass = [[myClass alloc] init];
        [_myClass setUpMyClass]; // this method just loads sounds and some text
    }
    return _myClass;
}

This is assuming your iVar for myClass is _myClass. If not, change _myClass to whatever the iVar is.

For future questions along the lines of "why does XXX crash" it's helpful if you include the debugger log and stack trace from the crash.

Upvotes: 4

Related Questions