Objective C:何时使用 NSCopying 以及何时使用 @属性(copy)?

Objective C: When to use NSCopying and and to use @property(copy)?

根据 Apple 文档:

NS复制 复制对象会创建一个与原始对象具有相同 class 和属性的新对象。当您想要对象包含的数据的您自己的版本时,您可以复制该对象。 https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectCopying.html

@属性(copy) 使用copy自动向新分配的对象发送一个-copy消息(这将创建一个副本传递的对象并将该副本分配给 属性 而不是 https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectCopying.html

我知道已经有很多关于这些概念的单独内容。

但是有人可以解释以下场景:

  1. 这两个可以互换使用

  2. 这两个需要一起使用才能实现一些东西。(因为如果我们创建一个自定义class如果我们创建这样一个[=的对象,系统将如何直接创建一个副本42=] 与 @属性(复制))?

当你使用@属性(copy)id xxx;确切的代码将是这样的:

-(id)xxx {   
  return [_xxx copy]; 
}

NSCopying是一个协议,表示class可以被复制。您需要实施 class 的复制方法才能使其正常工作。

我认为您误解了 copy 属性。它始终使用 NSCopying 行为。 NSCopying 定义了一个 copy 方法来从现有实例创建新实例,并且 copy 属性 使用此方法保存数据,而不是保留原始实例。

要了解 copy 属性 的必要性,首先我们必须了解可变对象和不可变对象之间的区别。例如,让我们看一下 NSMutableArrayNSArray。前者是可变的,后者是不可变的。当我们在某处传递 NSMutableArray 并保留它时,我们希望避免其他 类 改变我们的内部状态,这就是为什么我们要复制数组的当前值而不是保存原始可变数组。

例如:

@interface A : NSObject
@property (nonatomic, strong) NSArray *array1;
@property (nonatomic, copy) NSArray *array2;
@end

NSMutableArray *array = [NSMutableArray array];
[array addObject:@"a"];
[array addObject:@"b"];
[array addObject:@"c"];

A *a = [[A alloc] init];
a.array1 = array;
a.array2 = array;

// now we have changed the contents of a.array1 but a.array2 stays the same!
[array addObject:@"d"];

有趣的是,不可变对象不会 return 来自 copy 的新实例,它们 return self 因为如果一个对象是不可变的,它确实没关系。