可变和不可变之间有什么区别

时间:2011-08-15 21:35:29

标签: iphone objective-c

什么是可变和不可变的区别

NSString和NSMutableString。

NSArray和NSMutableArray。

NSDictionary和NSMutableDictionary。

可变对象和另一个对象[我猜不可变]之间有什么区别

@thanks提前。

8 个答案:

答案 0 :(得分:16)

可变对象可以变异或改变。不可变对象不能。例如,虽然您可以在NSMutableArray中添加或删除对象,但您无法使用NSArray。

可变对象可以更改,添加或删除元素,这是使用不可变对象无法实现的。不可变对象会被你在[[object alloc] initWith...]初始化程序中提供的任何输入所困扰。

你的可变对象的优点是显而易见的,但它们只应在必要时使用(这比你想象的要少得多),因为它们占用的内存比不可变对象多。

答案 1 :(得分:8)

可以修改可变对象,不可变对象不能。

例如: NSMutableArray有addObject: removeObject:个方法(以及更多),但NSArray没有。

修改字符串:

NSString *myString = @"hello";
myString = [myString stringByAppendingString:@" world"];

VS

NSMutableString *myString = @"hello";
[myString appendString:@" world"];

在处理数组时,可变对象特别有用,

例如,如果你有NSMrray的NSMutableStrings,你可以这样做:

[myArray makeObjectsPerformSelector:@selector(appendString:) withObject:@"!!!"];

将增加3个!到数组中每个字符串的末尾。

但是如果你有NSStrings的NSArray(因此是不可变的),你不能这样做(至少它比使用NSMutableString更难,更多的代码)

答案 2 :(得分:7)

基本区别是:

  • NSStrings无法编辑,只能重新分配。这意味着当NSString的值发生变化时,它实际上指向内存中的新位置。

  • 可以编辑NSMutableString对象并保持相同的指针。

一个常见的实际区别是:

  • 如果您创建了1个NSString,然后为其分配另一个NSString,则编辑其中任何一个NSString,它们现在将指向不同的字符串。

  • 如果您使用NSMutableStrings做同样的事情,但只编辑其中一个(不重新分配),它们都将指向新编辑的对象。

答案 3 :(得分:5)

可变对象可以变异或改变。不可变对象不能。例如,虽然您可以在NSMutableArray中添加或删除对象,但您无法使用NSArray。

答案 4 :(得分:2)

mutable”的英文定义实际上就是你所需要的。可以在创建后修改可变对象。创建后无法修改不可变对象。这适用于您列出的所有课程。

实际上,所有可变类都是不可变类的子类,并且每个类都添加了自己的接口以允许对对象进行编程修改,例如addObject:setObject:forKey:等...... / p>

答案 5 :(得分:2)

每个人都说您无法更改/修改不可变对象。我有不同的解释方式。你可以修改它,但是你会创建一个指向新对象的 new 指针,它不像你修改旧对象,它是一个品牌。新。宾语。任何先前指向它的指针都不会看到它的变化。但是,如果它是一个可变对象,任何以前指向它的对象都会看到它的 new 值。查看示例。 FYI %p在堆中打印指针位置。

 NSString * A = @"Bob";
    NSString * B = @"Bob";
    NSString * C = @"Bob1";
    NSString * D = A;
    NSLog(@"\n %p for A \n %p for B \n %p for C \n %p for D",A,B,C,D);

    // memory location of A,B,D are same.
  

0x104129068对于A
  对于B
,0x104129068    对于C
,0x104129088   D

的0x104129068

修改指针A的对象

A = @"Bob2"; // this would create a new memory location for A, its previous memory location is still retained by B
NSLog(@"\n%p for A \n%p for B \n%p for C \n %p for D",A,B,C, D);

// A has a **new** memory location, B,D have same memory location.
  

0x1041290c8为A
  对于B
,0x104129068   对于C
,0x104129088   0x104129068   对于D

// NSMutableString * AA = @"Bob"; <-- you CAN'T do this you will get error: Incompatible pointer types initializing NSMutableString with an Expression of type NSString
    NSMutableString * AA = [NSMutableString stringWithString:@"Bob1"];
    NSString * BB = @"Bob";
    NSString * CC = @"Bob1";
    NSString * DD = AA;
    NSLog(@"\n %p for AA \n %p for BB \n %p for CC \n %p for DD",AA,BB,CC,DD);

    // memory location of AA,DD are same.
  

0x7ff26af14490 for AA
  BB的0x104129068    CC为0x104129088   DD为0x7ff26af14490

修改指针AA的对象

  AA = (NSMutableString*)@"Bob3"; // This would NOT create a new memory location for A since its Mutable-- D was and still pointing to some location
    NSLog(@"\n%p for AA \n%p for BB \n%p for CC \n %p for D",AA,BB,CC,DD);

    // memory location of AA,DD are NOT same.
  对于AA,

0x104129128   BB的0x104129068   CC为0x104129088   DD为0x7ff26af14490

如您所想,所有NSString属性的默认存储属性为retain。有关copy&amp;的更多信息retain我强烈建议您阅读此问题。NSString property: copy or retain?

答案 6 :(得分:1)

Mutable可以改变,不可变的不可以。 当你共享一个可变对象时,你应该期望有人可以改变它。 当您共享一个不可变对象时,您预计没有人会改变。

答案 7 :(得分:1)

还有一些其他的区别是有趣的是不可变对象在复制时会被保留。苹果为了性能原因而实施的可能还有许多差异取决于对象是否可变,例如,子串方法是否复制其父字符串的实际字节,或者只是指向子字符串的子范围。父字符串,如果它是不可变的,可能不是,但谁知道。