Sam Pollard
Sam Pollard

Reputation: 77

Noob mystified by NSMutable array's behaviour

I'm a noob, trying to get my head around using XCode to put together a very simple interface for a very simple Mac app.

I've stripped my app down as much as possible to illustrate the snag I've hit.

My current interface consists of a single button.

In my AppController.h file I have the following:

    @interface AppController : NSObject 
    {
        NSMutableArray *ages;
        int price;
        NSString *culler;
    }
    -(IBAction) handleButtonClick: (NSButton*)sender;

    @end

and in my AppController.m file, I use my awakeFromNib method to set initial values:

    -(void)awakeFromNib
    {
        ages = [NSMutableArray arrayWithObjects: nil];
        [ages addObject: [NSNumber numberWithInt: 10]];
        [ages addObject: [NSNumber numberWithInt: 21]];

        price = 45;

        culler = [NSString stringWithString: @"bright green"];

        NSLog(@"waking up from nib, ages contains %i objects",[ages count]);
        NSLog(@"they are ...");
        for(int i = 0; i<[ages count]; i++)
        {
                NSLog(@"%i", [[ages objectAtIndex: i] integerValue]);
        }   

        NSLog(@"waking up from nib, the current price is %i", price);   
        NSLog(@"waking up from nib, the color is %@", culler);      

    }

That all seems to work fine, and I get the log messages I'm expecting.

But in my method for handling a click on my single button, I have the following:

-(void) handleButtonClick: (NSButton*) sender
{
    NSLog(@"you clicked the button");
    NSLog(@"after clicking the button, the current price is %i", price);
    NSLog(@"after clicking the button, the color is %@", culler);   

    NSLog(@"after clicking the button, ages contains %i objects",[ages count]);
    NSLog(@"they are ...");
    for(int i = 0; i<[ages count]; i++)
    {
            NSLog(@"%i", [[ages objectAtIndex: i] integerValue]);
    }   

}

When I click on the button, I get log messages telling me that 'culler' and 'prices' contain exactly what I expect (= exactly the values I gave them in 'awakeFromNib') but the program then spits out a "Program received signal: “EXC_BAD_ACCESS”" message and the beach ball puts in an appearance, as if it doesn't like me referring to my 'ages' array.

There's obviously something fundamental that I'm not understanding here. I can refer to my int and my NSString but not refer to my NSMutableArray?

I'm baffled.

If anyone could point me in the right direction I'd be very grateful.

Thank You for reading this.

Upvotes: 3

Views: 80

Answers (3)

kfrymire_noggin
kfrymire_noggin

Reputation: 1

You need to retain your array when you create it otherwise it'll get destroyed at the end of the current event loop. You can also use the [[alloc] init] style creation which doesn't necessarily require a retain.

Upvotes: 0

Hot Licks
Hot Licks

Reputation: 47719

It looks to me like you didn't retain ages. So it's going "poof" when the code "comes up for air" in the UI presentation.

You need to study up on storage management in Objective-C.

Upvotes: 1

sidyll
sidyll

Reputation: 59287

You're initializing your array with arrayWithObjects. Note this methods return an autoreleased object, that's probably not valid after your awakeFromNib ends.

Either add a retain message:

ages = [[NSMutableArray arrayWithObjects:nil] retain];

Or use a method that won't return an autoreleased object, such as the default alloc and init way:

ages = [[NSMutableArray alloc] initWithObjects:nil];

And be sure to read the Memory Management Guide.

Upvotes: 9

Related Questions