【问题标题】:NSMutableArray crashes when adding after proper initialization正确初始化后添加时 NSMutableArray 崩溃
【发布时间】:2011-02-23 22:20:44
【问题描述】:

我有一个定义为属性的 NSMutableArray,已合成并分配了一个新创建的 NSMutableArray 实例。但在此之后,每当我尝试向 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  

相关代码

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

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

【问题讨论】:

    标签: iphone objective-c nsmutablearray nsarray type-conversion


    【解决方案1】:

    问题是您已将该属性声明为copy。这意味着您的 setter 将像这样实现:

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

    这里的关键是,如果您 -copy 一个数组(无论是不可变的还是可变的),您将总是得到一个不可变的 NSArray

    因此,要解决此问题,请将属性更改为 retain 而不是 copy,并修复此内存泄漏:

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

    应该是:

    testPage.questions = [NSMutableArray array];
    

    【讨论】:

    • 嗯,没想到会这样,但它确实有效!我使用了copy,因为这里的很多问题都建议在某些东西是可变的时候使用副本。谢谢:D
    • @SpacyRicochet:当你想确保结果属性值是不可变时,你可以使用copy。你最常在NSString 属性中看到这一点:你copy 他们这样字符串本身就不会从你下面改变。由于您的属性假定是可变的,因此您不能使用copy。 :)
    • 谢谢!这将花费我更长的时间来弄清楚。 :)
    【解决方案2】:

    @property (nonatomic, copy) 这个 setter 声明“copy”可能转换为 NSArray 为什么不保留或分配?无论如何我都会保留

    【讨论】:

    • +1,尽管新值不会转换为 NSArray。该方法实际上是在制作一个不可变的副本。
    • 谢谢,顺便说一句,有什么方法可以查看像@property 这样的指令生成了什么代码?
    • 除了查看原始程序集之外,没有。
    【解决方案3】:

    你也可以像这样创建一个可变的复制方法:

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

    【讨论】:

    • 后来也发现了这一点。好方法,虽然我将它用于返回我想要更改的普通数组的方法。
    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 2016-04-08
    • 2018-03-15
    • 1970-01-01
    相关资源
    最近更新 更多