【问题标题】:Explain the difference between mutable and immutable可变和不可变有什么区别
【发布时间】:2011-10-27 14:49:57
【问题描述】:

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

喜欢

NSString 和 NSMutableString。

NSArray 和 NSMutableArray。

NSDictionary 和 NSMutableDictionary。

可变对象和其他对象有什么区别[我猜是不可变的]

@提前谢谢。

【问题讨论】:

  • 一个很好的后续问题是为什么 NSArray、NSString、NSSet、NSDictionary 等等。不可变的。

标签: iphone objective-c


【解决方案1】:

可变对象可以被改变或改变。不可变对象不能。例如,虽然您可以在 NSMutableArray 中添加或删除对象,但您不能对 NSArray 进行任何操作。

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

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

【讨论】:

  • 您可以接受答案而无需信誉积分。见:meta.stackexchange.com/questions/91889/…
  • FWIW,我不太确定可变对象本身会使用更多内存。我也认为这不是它们存在的主要原因。它们的存在是因为不可变对象可以更容易地在多线程环境中使用,AFAIK。
  • 如果您在应用程序中使用 NSMutableString 的任何地方都使用了 NSString - 我认为您会看到显着的性能下降。
【解决方案2】:

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

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

修改字符串:

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

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

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

例如,如果你有一个 NSMutableStrings 的 NSArray,你可以这样做:

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

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

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

【讨论】:

    【解决方案3】:

    基本区别是:

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

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

    一个常见的实际区别是:

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

    • 如果你对 NSMutableStrings 做同样的事情,然后只编辑其中一个(而不是重新分配它),它们都将指向新编辑的对象。

    【讨论】:

      【解决方案4】:

      可变对象可以被改变或改变。不可变对象不能。例如,虽然您可以在 NSMutableArray 中添加或删除对象,但您不能对 NSArray 进行任何操作。

      【讨论】:

      • 感谢 Glorified Hacker。我看 X-Man 电影,所以变种人可以在需要时改变那里的行为。在这里,对象是如何改变其行为的,你能给我举个例子吗......对不起我的电影例子。
      • 可变并不意味着对象的行为可以改变,它意味着数据可以改变。您可以将“World”添加到包含“Hello”的 NSMutableString 对象,但不能添加到包含“Hello”的 NSString 对象。
      • 感谢它在对象中的数据是可变的而不是不可变的 [Unchangeable] 非常感谢朋友。
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        每个人都说您不能更改/修改 不可变 对象。我有不同的解释方式。您可以修改它,但是您将创建一个指向新对象的 new 指针,它不像您修改旧对象,它是一个品牌。新的。目的。任何具有先前指向它的指针的指针都不会看到它的变化。然而,如果它是一个可变对象,任何先前指向它的对象都会看到它的 new 值。请参阅示例。 仅供参考%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
        0x104129068 为 B
        0x104129088 用于 C
        0x104129068 为 D


        修改指针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
        0x104129068 为 B
        0x104129088 用于 C
        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 用于 AA
        0x104129068 为 BB
        0x104129088 为 CC
        0x7ff26af14490 用于 DD


        修改指针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.
        

        0x104129128 用于 AA
        0x104129068 为 BB
        0x104129088 为 CC
        0x7ff26af14490 用于 DD

        正如你想象的那样,所有 NSString 属性的默认存储属性是retain。有关copyretain 的更多信息,我强烈建议您阅读此问题。NSString property: copy or retain?

        【讨论】:

        • 抱歉,这是混淆和不正确的混合体。您不能修改不可变对象,当然可以修改存储在引用类型变量中的值 - 从而更改引用的对象,您应该 从不 将字符串常量转换为 NSMutableString * - 它确实不创建可变字符串,分配给变量不会像答案似乎暗示的那样创建任何“新”内容,等等。
        • 对不起,没有。这需要相当多的重写,这里还有其他答案。
        • @CRD 很公平,但为了清楚起见,您只是在谈论我的第四个代码 sn-p 对吗?
        • 再次,抱歉,没有。您开始“每个人都说您不能更改/修改不可变对象。我有不同的解释方式。您可以修改它,但是...” - 您不能修改不可变对象。从一开始就在对象和存储对它们的引用的变量之间存在混淆。
        • @CRD 哦,现在我明白了。我明白你的意思并同意这一点。但只有我的措辞不同。我没有说你可以修改一个不可变的对象,指针是变化的。如果它正在更改相同的指针,那将是错误的......
        【解决方案7】:

        可变的可以改变,不可变的不能。 当您共享一个可变对象时,您应该期望有人可以更改它。 当您共享一个不可变对象时,您希望没有人会改变。

        【讨论】:

          【解决方案8】:

          还有一些其他有趣的区别,不可变对象在复制时将被保留。苹果出于性能原因实现的许多底层差异取决于对象是否可变,例如,子字符串方法是否复制其父字符串的实际字节或仅指向父字符串,如果它是不可变的,可能不是,但谁知道。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-12-17
            • 2012-10-10
            • 2019-05-29
            • 2019-02-03
            • 2016-10-19
            • 2014-09-28
            • 2019-10-02
            相关资源
            最近更新 更多