理解副本和可变副本

时间:2014-04-19 13:12:05

标签: objective-c copy semantics mutable

请考虑以下事项:

// BaseClass is both NSCopyable and NSMutableCopyable
@interface MyClass : BaseClass {
    // a bunch of properties
}

// x is a MyClass* local variable in a method
MyClass *a = [x copy];         // a is a strong reference to an immutable copy?
MyClass *b = [x mutableCopy];  // b is a strong reference to a mutable copy?

问题:

  1. 我可以对iVars进行任何更改吗?如果没有,如果我尝试对任何iVars进行更改会发生什么?我是否会获得不确定的行为,例如,有时候它会起作用,有时它不起作用,内存损坏,或编译器是否完全禁止它?

  2. 我可以对b的iVars进行任何更改吗?

1 个答案:

答案 0 :(得分:1)

简短回答

  1. 是。没有内存损坏,如果可以访问iVar,则没有编译错误。
  2. 与1相同。
  3. 答案很长

    可变和不可变副本是Apple基础课程中的核心概念之一,例如NSStringNSArray。如NSCopying协议中所述,实现“immutable vs mutable”概念的类必须返回copyWithZone: 的不可变对象。

    然而,编译器或内存保护并未强制实现对象的不变性,但类设计者必须设计该类以使其在收到copy消息时返回不可变对象。

    在您的情况下,实现此类操作的常用方法是使MyClass不可变,并将子类化为MyMutableClass并使其可变。您的呼叫网站应如下所示:

    MyClass *a = [x copy];         
    MyMutableClass *b = [x mutableCopy]; 
    

    请注意,实现mutable / immutable有时非常繁琐,因此请确保您有足够的理由来实现此类功能。