有人会非常友好地确认我正确理解这一点。我对此的初步回应是,mutableArray在分配给immutableArray时会变成immutableArray,但事实并非如此。
这是因为初始数组被分配为mutableArray,而immutableArray被指定为指向同一个对象。编译器发出警告,但代码在运行时执行得很好。
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"Teddy", @"Dog", nil];
NSArray *iArray = mArray;
[iArray addObject:@"Snoss"]; // Normally this would crash NSArray
非常感谢
加里。
答案 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。
但是,它不是干净的代码,你应该避免它。