分配,可变为不可变数组?

时间:2010-11-03 19:03:09

标签: iphone objective-c cocoa-touch

有人会非常友好地确认我正确理解这一点。我对此的初步回应是,mutableArray在分配给imm​​utableArray时会变成immutableArray,但事实并非如此。

这是因为初始数组被分配为mutableArray,而immutableArray被指定为指向同一个对象。编译器发出警告,但代码在运行时执行得很好。

NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"Teddy", @"Dog", nil];
NSArray *iArray = mArray;
[iArray addObject:@"Snoss"]; // Normally this would crash NSArray

非常感谢

加里。

4 个答案:

答案 0 :(得分:4)

不要混淆您创建的物理对象,以及您在代码中如何有效地投射

在这种情况下, 在物理上创建了一个NSMutableArray。

然后你有效地将它转换为NSArray - 这是完全有效的 - 例如,在许多情况下,函数可能需要NSArray,并且你可以传递NSArray或从它派生的任何东西(如NSMutableArray)

问题是你得到一个编译器警告,因为你试图在编译器认为只是一个NSArray的对象上调用addObject,因为这就是它的物理类型。

这实际上工作,因为它实际上 是一个NSMutableArray,而在运行时会响应该选择器

这样做是不好的编码实践,因为NSArray不会实际响应addObject选择器。例如,我可以创建一个函数,如:

-(void) addIt:(NSArray)myThing {
  [myThing addObject:@"New String"];
}

编译器会给你一个警告,说“NSArray”没有响应“addObject”选择器。如果你施放一个NSMutableArray,并将它传递给这个函数,那么它是myThing,它 实际上可以工作。

但这是不好的做法,因为如果你真的通过NSArray会崩溃。

摘要:不要混淆对象实际与您使编译器将其解释为的内容。

答案 1 :(得分:2)

是的,你是对的。你应该做

NSArray *array = [NSArray arrayWithArray:mutableArray];

确保没有人可以更改数组

答案 2 :(得分:1)

您的iArray实际上是引用NSMutableArray实例,这就是它是NSMutableArray的原因。

Obj-c没有严格检查类类型,所有对象都是'id'类型。 你可以写

NSNumber *iArray = mArray

编译器将显示错误演员的警告(不是错误)。但它会奏效。

不要乱用指针,没有像C ++那样的对象类型转换。 (有可重载的运算符用于将对象转换为另一个类)。

Obj-c可以像脚本/解释语言一样处理对象。动态类型(仅对象),反射,类实例方法的动态更改等 - 完全灵活。低级C / C ++速度与动态灵活性的完美结合。

答案 3 :(得分:0)

AFAIK,你是对的。 NSMutableArray是NSArray的子​​类,因此您可以毫不费力地将mArray分配给iArray。

但是,它不是干净的代码,你应该避免它。