5

我开始了一个小型 Xcode 项目来调查一个NSMutableString属性是否应该是copyretain. 我用属性声明了我的copy属性:

@property (nonatomic,copy) NSMutableString *stringA;

然后将其初始化为self.stringA = [NSMutableString new];

最后尝试设置一个字符串[stringA setString:@"A"];

然而,该程序给出,

“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'尝试使用 setString 改变不可变对象:'”

是因为结果字符串是 aNSString吗?这是否意味着我应该NSMutableString使用retain属性和NSString属性声明我的属性copy

4

2 回答 2

11

你是对的,copy方法NSMutableString返回一个不可变 NSString的。这是 Cocoa 中的约定,它也适用于NSMutableArray,NSMutableDictionary等。

因此,如果您希望您的属性保持可变,则应将其声明为retain. 如果您需要复制语义,但仍希望结果是可变的,则必须为属性实现自己的设置器(并用于mutableCopy进行复制)。

您经常看到copy字符串属性的原因是,通常需要保证字符串是不可变的,而不管分配给属性的字符串类型如何。否则,您最终可能会意外地在其他地方修改相同的字符串,这可能很难调试。不可变对象还具有线程安全的优点。

于 2012-08-16T17:55:44.317 回答
-1

我要问的第一个问题是 stringA 是如何初始化的。如果您从普通字符串设置它,那么这可能就是您得到它的原因。复制和保留实际上执行不同,您应该知道为什么要使用其中一种。

Copy 实际上是在制作内存的副本,以便您对该属性所做的任何更改都不会影响它设置的原始内容,其中保留只会增加内存的保留计数,因此您可以确保在完成之前不会释放它引用它。

于 2012-08-16T17:52:48.037 回答