2

This is really twisting my mind… I'm trying to access an NSMutableArray in an IBAction which I defined in viewDidLoad. Unfortunately I keep getting a EXC_BAD_ACCESS.

I'm new to all this so I'd really appreciate some insight in what I'm doing wrong.

Below find the corresponding code excerpts.

CounterViewController.h:

@interface CounterViewController : UIViewController{
 NSMutableArray *countHistoryArray;
}
@property(nonatomic, retain) NSMutableArray *countHistoryArray;

CounterViewController.m:

@implementation CounterViewController
@synthesize countHistoryArray;

- (void)viewDidLoad {
    [super viewDidLoad];

 //Fill array with some dummy data
 self.countHistoryArray = [[NSMutableArray alloc] init];
 NSDate *now = [[[NSDate alloc] init] autorelease];
 CurrentCount *historicCount = [[[CurrentCount alloc]
         initWithCount:[NSNumber numberWithInteger:22]
         description:@"Testcount"
         dateAndTime:now] autorelease];

 [self.countHistoryArray addObject: historicCount];

 //Do some logging - everything is working fine here!
 NSLog(@"%@", [self.countHistoryArray description]); 

}


//Later on we click on a button and want to use the array
- (IBAction)doSomeStuff {  
    //Let's look at the array again - and now it crashes with EXC_BAD_ACCESS
 NSLog(@"%@", [self.countHistoryArray description]);
}

Thanks a lot!
Manuel


EDIT Additional code as asked for by @jamapag

CurrentCount.h

#import <Foundation/Foundation.h>


@interface CurrentCount : NSObject {
    NSNumber *counterLevel;
    NSString *description;
    NSDate *dateAndTime;
}

- (id)initWithCount:(NSNumber *)newCounterLevel description:(NSString *)newDescription dateAndTime:(NSDate *)newDateAndTime;

@property(nonatomic, copy) NSNumber *counterLevel;
@property(nonatomic, copy) NSString *description;
@property(nonatomic, copy) NSDate *dateAndTime;

@end

CurrentCount.m

#import "CurrentCount.h"


@implementation CurrentCount
@synthesize counterLevel;
@synthesize description;
@synthesize dateAndTime;

- (id)initWithCount:(NSNumber *)newCounterLevel description:(NSString *)newDescription dateAndTime:(NSDate *)newDateAndTime{
    self = [super init];
    if(nil != self){
        self.counterLevel = newCounterLevel;
        self.description  = newDescription;
        self.dateAndTime  = newDateAndTime;
    }
    return self;
}


-(void) dealloc{
    self.counterLevel = nil;
    self.description  = nil;
    self.dateAndTime  = nil;
    [super dealloc];
}

@end
sprain
  • 7,552
  • 6
  • 35
  • 49
  • I think the problem is elsewhere, somewhere in between the two calls. However, this code has a leak at `self.countHistoryArray = [[NSMutableArray alloc] init]` -- you `alloc` the array, the property accessor will `retain`, but you don't `release`. You should either assign directly to the ivar or add an `autorelease`. It's probably worth checking for other questionable uses of `self.countHistoryArray = ...` which might be causing the trouble. – walkytalky Aug 02 '10 at 08:57
  • I do `-(void)dealloc {[self.countHistoryArray release];}` which I think does the job. Am I wrong? – sprain Aug 02 '10 at 09:14
  • In `-dealloc`, you should either call `-release` on the ivar itself: `[countHistoryArray release]`, or you should set the property to nil, which will release whatever was previously stored in the ivar, having exactly the same effect: `self.countHistoryArray = nil`. I prefer the second technique personally. – Nick Forge Aug 02 '10 at 09:40

4 Answers4

10

Are you sure that your code actually looks like this?

- (IBAction)doSomeStuff {  
    //Let's look at the array again - and now it crashes with EXC_BAD_ACCESS
    NSLog(@"%@", [self.countHistoryArray description]);
}

Your question title says "NSMutableArray count causes EXC_BAD_ACCESS" - if that line of code actually says NSLog(@"%@", [self.countHistoryArray count]);, you'll almost certainly get a crash, since NSLog will attempt to treat a primitive type (the type returned by -[NSArray count]) as an object. In order to use -[NSArray count] in NSLog, use %u instead of %@:

- (IBAction)doSomeStuff {  
    // This time it should work!
    NSLog(@"Array Count = %u", [self.countHistoryArray count]);
}
Nick Forge
  • 21,344
  • 7
  • 55
  • 78
  • Ha! Very good, that works! Thank you! (I did change from count to description somewhere during time). What I do not understand though is, `NSLog(@"%@", [self.countHistoryArray description]);` is now working, too. You say it can't work, but it does. Strange stuff… – sprain Aug 02 '10 at 09:23
  • `NSLog(@"%@", [self.countHistoryArray description]);` will work - my wording may have been slightly ambiguous. In an `NSLog` style format string, you should use `%@` for any Obj-C object, and an appropriate format symbol for any C primitives (`%u` for unsigned ints, `%f` for floats etc). Also, you can just use `NSLog(@"%@", self.countHistoryArray)`, since `NSLog` will call `description` on the object for you automatically. – Nick Forge Aug 02 '10 at 09:27
  • The reason I thought that this might be the case is because it's a common mistake, which I made many times when I was learning Obj-C (and occasionally still make when I'm tired enough). – Nick Forge Aug 02 '10 at 09:29
0

I know this question has already been solved and accepted but its for others who are or will face this issue.

I was facing the same issue, I tried all solutions but no solution worked for me. The project I am working on is NON-ARC.

I tried and made a simple change in property

Previously my property for NSMUTABLEARRAY was

@property (nonatomic, assign) NSMutableArray * dataArray;

I changed it to:

@property (nonatomic, retain) NSMutableArray * dataArray;

Changed it from ASSIGN to RETAIN

And it solved my problem

Omer Waqas Khan
  • 2,423
  • 4
  • 33
  • 62
0

Remove autorelease from:

currentCount *historicCount = [[[CurrentCount alloc] initWithCount:[NSNumber numberWithInteger:22] description:@"Testcount" dateAndTime:now] autorelease];

iPhoneDev
  • 2,995
  • 4
  • 33
  • 44
0

It looks like you are accidentally releasing countHistoryArray somewhere. Try removing all calls to it except for those two you showed. Additionally you can try enabling zombies to debug the problem.

Oh and by the way you probably don't really want a public NSMutableArray property and if you do you probably want it to be copy, not retain. Otherwise incapsulation kinda goes down the drain.

Community
  • 1
  • 1
SteamTrout
  • 1,684
  • 1
  • 13
  • 9