Objective-C:关于复制/保留NSString的简单问题

如果我将NSString设置为属性

@property (copy) NSString* name; 

我总是希望使用(复制),以便如果它的值改变,那么这个string的所有对象仍然具有旧值(如这里指定的)。

但是,如果我的NSString不是一个类属性,但它只是在代码中声明会发生什么? 在这种情况下,我每次分配一个新的值都会被保留或复制吗?

谢谢

这取决于你如何申报。 您应该阅读有关内存pipe理的文档 。 基本上这些规则是:

 NSString *aString = [NSString stringWithString:@"Hello"]; NSString *bString = [NSString stringWithFormat:@"%@", @"Hello"]; 

在这些情况下,string不会被复制或保留。 这是autoreleased,这意味着它会自动释放下次autorelease池消耗。 你不必调用它们的发布方法。 (所以分配一个新值不会导致泄漏。)

 NSString *cString = [[NSString alloc] initWithFormat:@"%@", @"Hello"]; [cString release]; 

根据Objective C约定,使用alloc且保留数为1的方法不是自动发布的,因此您需要明确地发布它们。 指定一个新的值而不释放旧的值会导致泄漏。

您还可以显式调用string上的“复制”方法或“保留”方法。 在任何一种情况下,新string的保留计数都是1,并且不会被自动释放,所以您在分配新值之前需要调用release方法。

 NSString *dString = [cString retain]; NSString *eString = [cString copy]; ... [dString release]; [eString release]; 

如果它是一个属性,并且你使用self.variableName,这将会被照顾(通过@synthesize生成的getter和setter)。 如果你明确地做了,你必须确保调用释放你调用的保留或复制的variables。

编辑:正如以下一些评论家所指出的那样,从“所有权”的angular度来看待pipe理通常是描述这些想法的首选,而不是保留点数。

如果它不是一个属性,只是在代码中声明,你需要明确地保留或复制它,即

 NSString myString = [otherString copy]; 

要么

 NSString myString = [otherString retain]; 

无论哪种方式,你也需要确保它在某个时候被释放。

如果你没有使用属性的setter,比如self.name = @"foo"或者[self setName:@"foo"] ,而是直接赋值variables,比如name = @"foo" ,那没关系根本就是如何宣布财产。

你必须明白,属性语法只是写访问方法的一个快捷方式(在这种情况下是-name-setName: 。 如果你没有调用这些方法(隐式地通过设置属性),它们在内部是如何工作的(这是你通过retain或者copy指定的)。