何时使用setter属性';复印件';在objective-c中?

何时使用setter属性';复印件';在objective-c中?,objective-c,ios,ios5,setter,Objective C,Ios,Ios5,Setter,我知道,通常情况下,您会对NSStrings使用copy,这样,即使有人试图在其他地方重新设置属性,您的属性也会保持与分配属性时相同的值 但我很难完全理解这个概念。这难道不适用于任何类型的对象(不仅仅是NSString) 所以我的问题是,“我应该设置什么类型的属性为‘复制’,为什么?”客户端代码可以将NSMutableString对象分配给NSString属性。如果属性被定义为强属性或其他非复制属性,那么如果客户端稍后更改可变字符串,则属性的值现在将不同。通过将属性设置为“copy”,将创建字符

我知道,通常情况下,您会对NSStrings使用copy,这样,即使有人试图在其他地方重新设置属性,您的属性也会保持与分配属性时相同的值

但我很难完全理解这个概念。这难道不适用于任何类型的对象(不仅仅是NSString)


所以我的问题是,“我应该设置什么类型的属性为‘复制’,为什么?”

客户端代码可以将NSMutableString对象分配给NSString属性。如果属性被定义为强属性或其他非复制属性,那么如果客户端稍后更改可变字符串,则属性的值现在将不同。通过将属性设置为“copy”,将创建字符串值的副本,从而确保该值不会在背后更改


因此,基本上,只要属性用于具有可变对应项的类型,并且希望确保值不会在您身上更改,您就应该使用copy。

简单数据位(如字符串)的对象不会引用应用程序中的大量其他对象,非常适合复制


当然,现在您可以保留字符串之类的内容。这很好用。但是如果你有一个可变的字符串,然后你修改了它呢。现在,所有引用该字符串的其他对象都将看到该修改。这可能不是你想要的。这是复制“更简单”的一个原因,因为对该数据的任何更改都只局限于该代码位

另一方面,假设您有一个为应用程序编写的类的实例。它引用了应用程序中的其他对象,它有大量自己的字符串或其他值,是一个复杂的野兽。现在复制这个对象可能不是个好主意。很可能,如果修改此对象,则希望将更改传播到包含引用的每个对象。即使您复制了它,您需要浅拷贝(一个新实例,但它的ivar引用相同的对象)还是深拷贝(一个包含每个ivar新副本的新实例)?而且所讨论的对象甚至可能不支持
,这意味着它在技术上根本无法复制


综上所述:

  • copy
    :对象是小的原子数据位,没有对其他对象的任何内部引用
  • 保留
    :几乎所有其他类型的对象

也会阻塞,因为必须在所有支持协议的类中传递当前作用域变量。复制的对象具有相同的数据,但引用了中的另一个地址memory@NeverBe这是误导。虽然您可以将它用于实现
NSCopying
的任何类,但问题是您应该何时使用它。块是一种特殊情况,因为一旦它们的堆栈帧消失而没有副本,它们就合法地变得无用。否则,我唯一能想到的一般规则是“为了避免数据的其他所有者对其进行重击,而不是在对象之间共享所有权,您希望拥有一个可变数据的副本”@NeverBe同样,您不会总是获得不同的内存地址,因此声明它这样做可能会产生误导。有些对象即使在被复制后,如果知道它们是不可变的,也会返回它们自己的内存地址作为优化。但是如果你有一个可变字符串,并对它进行了修改,会怎么样呢。很抱歉,我们可以修改可变字符串吗?这并不能真正回答问题。OP想知道字符串有什么特别之处?为什么不复制任何可变对象@亚历克斯韦恩解释得很好。