NSString属性是复制还是只读?

时间:2011-11-03 03:39:58

标签: objective-c memory-management properties nsstring

我看到很多讨论说我应该使用复制来获取NSString属性,因为它会阻止其他人在我背后更改它。但那么为什么我们不为它设置 readonly 属性呢?

更新

感谢您回答我的问题。但问题是,对于NSString属性,你总是不希望别人修改它,对吧?您可以自己修改它,但绝对不能修改其他人。我猜大多数时候NSString都会设置它的初始值(由你或其他人设置),之后只有你会修改它。那么为什么不只使用readonly属性

实际上我大部分时间都在使用副本。但后来我发现大部分时间我只在init方法中使用那些setter。所以我认为我应该使用readonly而不是copy来处理这些情况。

因此,让我以这种方式提出问题:如果您只在init方法中使用这些setter作为NSStrings,那么您应该使用readonly。这是一个合理的结论吗?

2 个答案:

答案 0 :(得分:12)

  

如果您只在init方法中为NSStrings使用这些setter,那么您应该使用readonly。这是一个合理的结论吗?

由于您不应在部分构造状态(init / dealloc)中使用访问器,因此您应将其声明为copyreadonly,然后执行复制初始化器:

- (id)initWithName:(NSString *)inName
{
  self = [super init];
  if (0 != self) {
    name = [inName copy];
  }
  return self;
}

更详细地说,copyreadonly在语义上是不同的概念。

  • 您使用copy因为您对大多数情况下的值感兴趣。它也是使用不可变字符串的安全措施和优化。

  • 您使用readonly禁止客户变更/设置您的数据。

它们共同提供了一定程度的安全性,但仅此一项:

  • copy仍允许客户通过设置器在程序执行的任何位置设置值。

  • readonly并不意味着copy,并且可以在您的背后更改保留的财产;考虑当你传递一个可变变量时会发生什么,并且客户端在调用setter之后会改变它。

最安全的方法是使用copyreadonly

  • 显然,当您需要为客户提供设置器时,您将使用readwrite,并且您支持该更改。

  • 保留字符串(或数组,或......)而不是复制通常是一个坏主意。很难有一个很好的用途,你不要复制这些类型,它可能会导致微妙的错误。即使你正在处理一个可变类型,你通常也会想要一个可变副本(编译器不会为你合成)。保留或分配这些类型几乎不是你想要的。我所做的一个例外是处理大量分配时,数据封装得很好(例如,我将所有权从一个地方传递到另一个地方以避免复制的重NSMutableData个实例。

答案 1 :(得分:6)

如果您不希望其他人修改您的媒体资源,那么您绝对应该将其标记为readonly。人们说使用copy意味着字符串不能在你的背后改变是什么意思,如果有人为你的属性分配一个字符串,并且字符串是可变的,然后他们改变字符串,当你以后访问您的媒体资源,您将获得已更改的字符串。但是如果您使用copy,那么您将获得一个快照,了解字符串在分配给该属性时的状态(这是人们期望发生的事情)。