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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5988629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:54:16  来源:igfitidea点击:

objective-C: simple question about copy/retain NSString

objective-cios

提问by aneuryzm

If I set a NSString as property

如果我将 NSString 设置为属性

@property (copy) NSString* name;

I always want to use (copy), so that if its value change, all object with such string still have the old value (as specifiedhere).

我总是想用(复印件),这样,如果它的价值变化,这样的字符串中的所有对象仍然有旧值(指定位置)。

However, what happens if my NSString is not a class property, but it is just declared in the code ? Is in that case retained or copied everytime I assign a new value ?

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

thanks

谢谢

回答by Matthew Gillingham

It depends on how you declare it. You should read the documentationon memory management. Basically the rules are:

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

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

In these cases, the string is not copied or retained. It is autoreleased, which means it will be automatically deallocated the next time the autorelease pool drains. You do not have to call the release method on them. (So assigning a new value will not cause it to leak.)

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

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

According to Objective C convention, methods that use alloc and have a retain count of one are not autoreleased, so you need to release them explicitly. Assigning a new value without releasing the old one will cause a leak.

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

You can also explicitly call a "copy" method or a "retain" method on a string. In either case, the new string will have a retain count of 1 and will not be autoreleased, so you will need to call the release method on it before you assign a new value.

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

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

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

If it is a property, and you use self.variableName, this will be taken care of for you (through the getters and setters which are generated with @synthesize). If you do it explicitly, you must make sure to call release on variables that you have called retain or copy on.

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

Edit:As some commentators below have noted, thinking about management in terms of "ownership" is usually the preferred of describing these ideas, rather than retain count.

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

回答by Tom Jefferys

If it's not a property and just declared in code, you need to explicitly retain or copy it, ie

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

NSString myString = [otherString copy];

or

或者

NSString myString = [otherString retain];

Either way you also need to ensure it's released at somepoint.

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

回答by omz

If you're not using the property's setter, like self.name = @"foo"or [self setName:@"foo"], but rather assign the variable directly, like name = @"foo", it doesn't matter at all how the property is declared.

如果您不使用属性的 setter,例如self.name = @"foo"[self setName:@"foo"],而是直接分配变量,例如name = @"foo",则属性的声明方式完全无关紧要。

You have to understand that the property syntax is just a shortcut for writing accessor methods (-nameand -setName:in this case). If you're not calling these methods (implicitly by setting the property), it doesn't matter how they work internally (which is what you specify by retainor copy).

你必须明白,属性语法只是一个快捷方式编写存取方法(-name-setName:在这种情况下)。如果您不调用这些方法(通过设置属性隐式调用),则它们在内部的工作方式无关紧要(这是您通过retain或指定的copy)。