如果我将NSString设置为属性
@property (copy) NSString* name;
我总是想使用(复制),这样如果它的值发生变化,那么所有带有这种字符串的对象仍然具有旧值(如指定的here)。
但是,如果我的NSString不是类属性会发生什么,但它只是在代码中声明了?在每次分配新值时是保留还是复制?
感谢
答案 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:
)。如果您没有调用这些方法(通过设置属性隐式),那么它们在内部的工作方式并不重要(这是您retain
或copy
指定的方式)。