开发者

NSMutableArray crashes when adding after proper initialization

开发者 https://www.devze.com 2023-02-13 14:36 出处:网络
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 obj

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开发者_StackOverflow社区 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?


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];


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


You can also create a mutable copy method like so:

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

精彩评论

暂无评论...
验证码 换一张
取 消