NSMutableArray在正确初始化之后添加了崩溃。

时间:2021-05-27 20:16:04

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.

我有一个定义为属性的NSMutableArray,并进行了合成,并分配了一个新创建的NSMutableArray实例。但在此之后,每当我尝试向NSMutableArray中添加对象时,我的应用程序总是会崩溃。

Page.h

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

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?

调试器显示,当我使用testPage时。问题= [NSMutableArray alloc] init;testPage的类型。问题从NSMutableArray*变为__NSArrayL*(或__NSArrayI*,不确定)。我怀疑这是问题所在,但我觉得这很奇怪。有人知道这里发生了什么吗?

3 个解决方案

#1


4  

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

问题是,您已经将属性声明为副本。这意味着你的setter将被实现如下:

- (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.

这里的要点是,如果您复制一个数组(无论是不可变的还是可变的),您总是会得到一个不可变的NSArray。

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

为了修复这个问题,将属性改为retain而不是copy,同时也修复这个内存泄漏:

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

It should be:

应该是:

testPage.questions = [NSMutableArray array];

#2


2  

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

@property (nonatomic, copy)这个setter声明“copy”可能被强制转换为NSArray,为什么不保留或分配呢?不管怎样我都将保留

#3


1  

You can also create a mutable copy method like so:

您还可以创建一个可变复制方法,如下所示:

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

#1


4  

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

问题是,您已经将属性声明为副本。这意味着你的setter将被实现如下:

- (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.

这里的要点是,如果您复制一个数组(无论是不可变的还是可变的),您总是会得到一个不可变的NSArray。

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

为了修复这个问题,将属性改为retain而不是copy,同时也修复这个内存泄漏:

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

It should be:

应该是:

testPage.questions = [NSMutableArray array];

#2


2  

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

@property (nonatomic, copy)这个setter声明“copy”可能被强制转换为NSArray,为什么不保留或分配呢?不管怎样我都将保留

#3


1  

You can also create a mutable copy method like so:

您还可以创建一个可变复制方法,如下所示:

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