Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSMutableArray对象认为它是NSArray:(_Iphone_Objective C_Cocoa - Fatal编程技术网

Iphone NSMutableArray对象认为它是NSArray:(

Iphone NSMutableArray对象认为它是NSArray:(,iphone,objective-c,cocoa,Iphone,Objective C,Cocoa,因此,我有一个属性NSMutableArray*grades。在我唯一设置此属性的地方,我正在执行以下操作: NSMutableArray *array = [[NSMutableArray alloc] init]; self.grades = array; [array release]; [self.grades addObject:@"20"]; 最后一条语句生成一个异常:-[NSCFArray insertObject:atIndex:]:mutating方法发送到不可变对象

因此,我有一个属性
NSMutableArray*grades
。在我唯一设置此属性的地方,我正在执行以下操作:

NSMutableArray *array = [[NSMutableArray alloc] init];
self.grades = array;    
[array release];
[self.grades addObject:@"20"];
最后一条语句生成一个异常:
-[NSCFArray insertObject:atIndex:]:mutating方法发送到不可变对象'


我到底错过了什么?

确保
grades
是一个
NSMutableArray

编辑:

copy
返回一个不可变的副本,因此您无法进行更改。来自Apple的:

复制 如果使用“复制声明”属性,则指定在赋值过程中复制值。如果合成相应的访问器,则合成的方法使用“复制”方法。这对于字符串对象等属性非常有用,因为在这些属性中,在setter中传递的新值可能是可变的(例如,NSMutableString的一个实例),并且您希望确保您的对象具有自己的私有不可变副本。例如,如果您按如下方式声明属性:

虽然这对字符串很有效,但如果属性是集合(如数组或集合),则可能会出现问题。通常,您希望此类集合是可变的,但是copy方法返回集合的不可变版本。在这种情况下,您必须提供自己的setter方法实现,如下所示:如下面的示例所示

在分配时复制整个集合是一项繁重的操作。您确定不想
保留该集合,还是只想
分配它

如果你真的想要一个可变副本,那么按照文档的建议编写你自己的setter

- (void)setGrades:(NSMutableArray *)array {
    // make shallow/deep copy here, and assign to `grades`, not `self.grades`
}

等级
声明为什么

从错误消息的外观来看,您声明
分级为NSArray,虽然这是有效的,但确实意味着您失去了数组的可变性

要将数组保持为可变的,还需要将grades声明为NSMutableArray

编辑:


根据您的编辑,原因可能是您在属性中使用了
copy
关键字,这意味着当您使用
self.grades
分配数组时,综合setter方法会生成
array

的不可变副本,这听起来像是将属性设置为
copy
,这意味着synthesized accessor生成数组的不可变副本。如果声明为
@property NSArray*grades
,grades可能会返回一个NSArray。看到这一点,编译器会感到奇怪,不想支持
addObject:
方法。您有两个选项

  • 投 像[(NSMutableArray*)self.grades addObject:
  • 在指定对象之前添加对象 数组

  • 编辑以显示正确的属性名称(它是
    grades
    ,而不是
    stuff
    )。对此很抱歉。它是:
    @property(非原子,复制)NSMutableArray*grades;
    将其更改为
    (非原子,保留)
    为什么首先需要复制它?从原始post中的代码分配数组并将其传递给实例变量
    grades
    ,然后释放原始对象。这与仅使用retain调用的行为相同。类
    grades
    静态声明为与wha无关对象实际上是不可变的。它不会使它不可变。编译时会收到警告,但肯定不是运行时错误。这是运行时异常。编译器只会生成警告。