0

When my program gets to the line: [userNumSequence addObject:[NSNumber numberWithInteger: sequenceNumber]]; it gets the error: Program received signal: “EXC_BAD_ACCESS”.

All I'm wanting to do is to store an integer in the array.

//  JBNumberGeneration.m

#import "JBNumberGeneration.h"


@implementation JBNumberGeneration

- (id) init{ 
    if (self = [super init]){ 
        userNumSequence = [NSMutableArray arrayWithCapacity:0]; 
    } return self; 
}

-(IBAction)logSequenceNumber:(id)sender{
    NSString *titleOfButton = [sender title];
    int sequenceNumber = [titleOfButton integerValue];
    i=0;

    [userNumSequence addObject:[NSNumber numberWithInteger: sequenceNumber]];

    //int currentNum = [((NSNumber*)[userNumSequence objectAtIndex: i]) integerValue];
    //NSLog(@"%i", currentNum);

    int count = [userNumSequence count];
    NSLog(@"Array size: %i", count);

    i++;
}
@end

//  JBNumberGeneration.h

#import <Cocoa/Cocoa.h>


@interface JBNumberGeneration : NSObject {
    IBOutlet NSTextField *displayLabel;
    int randNum;
    int level;
    int i;
    NSMutableArray* userNumSequence;
}

-(IBAction)logSequenceNumber:(id)sender;
@end

1 Answer 1

3

EXC_BAD_ACCESS usually occurs when you try to access a member that has already been deallocated. Because you are calling [NSMutableArray arrayWithCapacity:] in your init function, it may have already been released by the time logSequenceNumber:(id)sender is called. Try adding @property (nonatomic, retain) NSMutableArray* userNumSequence to your @interface and @synthesize userNumSequence to your @implementation. Then call self.userNumSequence = [NSMutableArray arrayWithCapacity:0] in your init method. Don't forget to set it to nil in dealloc.

EDIT: Also, just to be clear the Cocoa memory management naming standards are like this:

  1. If you call [[Object alloc] initSomehow], or [object retain] you are responsible for releasing it (calling init methods will automatically call retain).
  2. If you call methods like [Object objectWithSomething:something], these are usually autoreleased and will be released sometime in the future. You should never assume these exist beyond the scope in with they are created. According to the Cocoa documentation, scope includes the call stack. If a: calls b: which calls c:, and c: returns an autoreleased object, it can be passed safely all the way back up for a: to use. Beyond that it is released. This is at least my interpretation of the explanation of autorelease.

If you need to use something for the lifetime of your object, retain it when you get it and release it in dealloc.

Sign up to request clarification or add additional context in comments.

7 Comments

No problem. Objective-C memory management can be a bit weird if you're not used to it.
Sorry, you are wrong. init does not automatically call retain. Alloc has an implicit retain, not init. Also it is considered a bad idea to use properties in init. It's far better in this case just to alloc and init the array in init.
I mean, you are wrong on those two specific issues. You are correct that the array is not retained in the questioner's code and this is why it goes away.
@Jeremy. Good to know. I knew the [[alloc] init] call does retain, but I just took a stab and guessed init called retain. Also, why is it considered a bad idea to use properties in init? It's just a call to a setter that releases the current instance, retains the new one, and assigns it to the ivar.
You can't be certain that the setter just releases the old value, retains the new value and sets the value to the new value. The setter is an Objective-C method and can potentially do anything it likes.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.