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

时间:2011-05-13 07:26:24

标签: objective-c ios

如果我将NSString设置为属性

@property (copy) NSString* name;

我总是想使用(复制),这样如果它的值发生变化,那么所有带有这种字符串的对象仍然具有旧值(如指定的here)。

但是,如果我的NSString不是类属性会发生什么,但它只是在代码中声明了?在每次分配新值时是保留还是复制?

感谢

3 个答案:

答案 0 :(得分:9)

这取决于你如何宣布它。您应该阅读有关内存管理的documentation。基本上规则是:

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

在这些情况下,不会复制或保留字符串。它是自动释放的,这意味着它将在下次自动释放池耗尽时自动解除分配。您不必在它们上调用release方法。 (因此,分配新值不会导致泄漏。)

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

根据Objective C约定,使用alloc并且保留计数为1的方法不会自动释放,因此您需要显式释放它们。在不释放旧值的情况下分配新值将导致泄漏。

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

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

...
[dString release];
[eString release];

如果它是一个属性,并且你使用self.variableName,那么这将由你来处理(通过使用@synthesize生成的getter和setter)。如果明确地执行此操作,则必须确保对已调用保留或复制的变量调用release。

编辑:正如下面的一些评论员所指出的那样,在“所有权”方面考虑管理通常是描述这些想法的首选,而不是保留计数。

答案 1 :(得分:4)

如果它不是属性并且只是在代码中声明,则需要明确保留或复制它,即

NSString myString = [otherString copy];

NSString myString = [otherString retain];

无论哪种方式,你还需要确保它在某个时候发布。

答案 2 :(得分:2)

如果您没有使用该属性的设置器,例如self.name = @"foo"[self setName:@"foo"],而是直接指定变量,例如name = @"foo",那么属性如何无关紧要宣布。

您必须了解,属性语法只是编写访问器方法的快捷方式(在本例中为-name-setName:)。如果您没有调用这些方法(通过设置属性隐式),那么它们在内部的工作方式并不重要(这是您retaincopy指定的方式)。