尝试使用复制的NSMutableString属性会导致异常

时间:2012-08-16 17:49:06

标签: objective-c cocoa nsmutablestring declared-property

我启动了一个小型Xcode项目来调查NSMutableString属性应该是copy还是retain。我使用copy属性声明了我的属性:

@property (nonatomic,copy) NSMutableString *stringA;

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

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

然而程序给出了,

  

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

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

2 个答案:

答案 0 :(得分:11)

您是对的,copy NSMutableString方法会返回不可变 NSString。这是Cocoa中的约定,它也适用于NSMutableArrayNSMutableDictionary等。

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

您通常看到copy字符串属性的原因是,通常需要保证字符串是不可变的,而不管为该属性分配了什么类型的字符串。否则,您最终可能会意外地在其他位置修改相同的字符串,这可能很难调试。不可变对象还具有线程安全的好处。

答案 1 :(得分:-1)

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

复制实际上是在制作一个内存副本,这样你对该属性所做的任何更改都不会影响它所设置的原始内容,其中retain只会增加内存的保留计数,所以你要确保它不会被释放。你完成了它的引用。