SpacyRicochet
SpacyRicochet

Reputation: 2279

NSMutableArray crashes when adding after proper initialization

I have an NSMutableArray defined as a property, synthesized and I have assigned a newly created instance of an NSMutableArray. But after this my application always crashes whenever I try adding an object to the NSMutableArray.

Page.h

@interface Page : NSObject  
{  
    NSString *name;  
    UIImage *image;  
    NSMutableArray *questions;  
}
@property (nonatomic, copy) NSString *name;  
@property (nonatomic, retain) UIImage *image;  
@property (nonatomic, copy) NSMutableArray *questions;  
@end

Page.m

@implementation Page  
@synthesize name, image, questions;  
@end  

Relevant code

Page *testPage = [[Page alloc] init];  
testPage.image = [UIImage imageNamed:@"Cooperatief  leren Veenman-11.jpg"];  
testPage.name = [NSString stringWithString:@"Cooperatief  leren Veenman-11.jpg"];  
testPage.questions = [[NSMutableArray alloc] init];  
[testPage.questions addObject:[NSNumber numberWithFloat:arc4random()]];  

The debugger reveals that the moment I use testPage.questions = [[NSMutableArray alloc] init]; the type of testPage.questions changes from NSMutableArray* to __NSArrayL* (or __NSArrayI*, not sure). I suspect this to be the problem, but I find it extremely odd. Anyone know what's happening here?

Upvotes: 3

Views: 853

Answers (3)

Damien Cooke
Damien Cooke

Reputation: 51

You can also create a mutable copy method like so:

- (void)setQuestions:(NSMutableArray *)newArray
{
    if (questions != newArray) 
    {
        [questions release];
        questions = [newArray mutableCopy];
    }
}

Upvotes: 1

Dave DeLong
Dave DeLong

Reputation: 243146

The problem is that you've declared the property as copy. This means your setter is going to be implemented something like this:

- (void) setQuestions:(NSMutableArray *)array {
  if (array != questions) {
    [questions release];
    questions = [array copy];
  }
}

The kicker here is that if you -copy an array (whether immutable or mutable), you will always get an immutable NSArray.

So to fix this, change the property to be retain instead of copy, and also fix this memory leak:

testPage.questions = [[NSMutableArray alloc] init];

It should be:

testPage.questions = [NSMutableArray array];

Upvotes: 4

Michal
Michal

Reputation: 133

@property (nonatomic, copy) This setter declaration "copy" probably cast to NSArray why not retain or assign? I would retain anyway

Upvotes: 2

Related Questions