可以从getter返回属性副本吗?

时间:2021-09-15 23:07:27

I have following simple class:

我有以下简单的课程:

@interface Article: NSObject {
    NSString *title;
}
@property (copy, nonatomic) NSString *title;
@end

@implementation

- (void)setTitle:(NSString *)aString {
    if ((!title && !aString) || (title && aString && [title isEqualToString:aString])) return;
    dirty = YES;
    [title release];
    title = [aString copy];
}

- (NSString *)title {
    return title;
}

@end

In my application I have to do a lot of things like

在我的应用程序中,我必须做很多事情

Article *article= [objectsArray getObjectAtIndex:x];
NSString *title=article.title;
UILabel.text=title;
[title release];

I know I'm supposed to call retain when I get the property:

我知道当我拿到房产时我应该叫保留:

NSString *title=[article.title retain];

Maybe I am lazy to do a retain where I get the propery. Or If I need to do that tens of times all over the applicaiton.

也许我懒得去保留我得到的地方。或者如果我需要在整个应用程序中执行数十次。

Can I have getter to return a copy?

我可以得到一份副本吗?

- (NSString *)title {
    return [title copy];
}

3 个解决方案

#1


There are some circumstances where I prefer to return a copy of the property for safety reasons. For example, if I'm writing a class that has a unique identifier property, then I'll "return [[_uniqueID copy] autorelease]" so that there's no chance that another class could do anything to the unique identifier. Other times I'll just return the object itself, because it's not a big deal if it's externally manipulated.

在某些情况下,出于安全原因,我更愿意退回该物业的副本。例如,如果我正在编写一个具有唯一标识符属性的类,那么我将“返回[[_uniqueID copy] autorelease]”,以便其他类不可能对唯一标识符执行任何操作。其他时候我只会返回对象本身,因为如果外部操作它并不是什么大问题。

Also, with respect to these getter methods, they should not return objects with a +1 retain count (which is what you have going). If anything, they should return the object directly or return it with a +0 retain count (retain/copy + autorelease). It greatly simplifies your memory management to do it that way. If the external object needs to hold on to the returned object, then the external object should be responsible for retaining whatever it needs.

此外,对于这些getter方法,它们不应该返回具有+1保留计数的对象(这就是你要去的)。如果有的话,他们应该直接返回对象或者返回+0保留计数(保留/复制+自动释放)。它大大简化了你的内存管理,就这样做了。如果外部对象需要保留返回的对象,那么外部对象应该负责保留它所需的任何内容。

#2


It's a good idea to return a copy of mutable properties so other objects can't change your object out from under you.

返回一个可变属性的副本是个好主意,这样其他对象就无法从你身下改变你的对象。

In the case of a plain NSString, since it is immutable, both copy and retain do the same thing — they retain the string and return it.

在普通NSString的情况下,因为它是不可变的,所以复制和保留都做同样的事情 - 它们保留字符串并返回它。

#3


On Chuck's note, you'll often see (NSMutableString *) properties return a copy of the object, rather than a reference to the original string. Like he points out, this is a safety mechanism, allowing you to deal with a "snapshot" of the string at the time it is accessed.

在Chuck的注释中,您经常会看到(NSMutableString *)属性返回对象的副本,而不是对原始字符串的引用。就像他指出的那样,这是一种安全机制,允许您在访问时处理字符串的“快照”。

In your particular example, however, it looks like the title property is set once and then accessed to be used as text in a UILabel.

但是,在您的特定示例中,看起来title属性设置一次,然后被访问以用作UILabel中的文本。

If this is your only application, you technically don't have to retain the NSString when you get it from the accessor.

如果这是您唯一的应用程序,从技术上讲,从访问者那里获取NSString时不必保留NSString。

NSString * articleTitle = article.title;
label.text = articleTitle;
articleTitle = nil;

The UILabel will store a retained copy of the string when its 'text' property is set. You can 'nil' the reference after setting the text, and you'll get the same result. No extra retain/release involved. (Although it may be good practice)

UILabel将在设置“text”属性时存储字符串的保留副本。设置文本后,您可以“nil”引用,您将获得相同的结果。不涉及额外的保留/释放。 (虽然这可能是一个好习惯)

#1


There are some circumstances where I prefer to return a copy of the property for safety reasons. For example, if I'm writing a class that has a unique identifier property, then I'll "return [[_uniqueID copy] autorelease]" so that there's no chance that another class could do anything to the unique identifier. Other times I'll just return the object itself, because it's not a big deal if it's externally manipulated.

在某些情况下,出于安全原因,我更愿意退回该物业的副本。例如,如果我正在编写一个具有唯一标识符属性的类,那么我将“返回[[_uniqueID copy] autorelease]”,以便其他类不可能对唯一标识符执行任何操作。其他时候我只会返回对象本身,因为如果外部操作它并不是什么大问题。

Also, with respect to these getter methods, they should not return objects with a +1 retain count (which is what you have going). If anything, they should return the object directly or return it with a +0 retain count (retain/copy + autorelease). It greatly simplifies your memory management to do it that way. If the external object needs to hold on to the returned object, then the external object should be responsible for retaining whatever it needs.

此外,对于这些getter方法,它们不应该返回具有+1保留计数的对象(这就是你要去的)。如果有的话,他们应该直接返回对象或者返回+0保留计数(保留/复制+自动释放)。它大大简化了你的内存管理,就这样做了。如果外部对象需要保留返回的对象,那么外部对象应该负责保留它所需的任何内容。

#2


It's a good idea to return a copy of mutable properties so other objects can't change your object out from under you.

返回一个可变属性的副本是个好主意,这样其他对象就无法从你身下改变你的对象。

In the case of a plain NSString, since it is immutable, both copy and retain do the same thing — they retain the string and return it.

在普通NSString的情况下,因为它是不可变的,所以复制和保留都做同样的事情 - 它们保留字符串并返回它。

#3


On Chuck's note, you'll often see (NSMutableString *) properties return a copy of the object, rather than a reference to the original string. Like he points out, this is a safety mechanism, allowing you to deal with a "snapshot" of the string at the time it is accessed.

在Chuck的注释中,您经常会看到(NSMutableString *)属性返回对象的副本,而不是对原始字符串的引用。就像他指出的那样,这是一种安全机制,允许您在访问时处理字符串的“快照”。

In your particular example, however, it looks like the title property is set once and then accessed to be used as text in a UILabel.

但是,在您的特定示例中,看起来title属性设置一次,然后被访问以用作UILabel中的文本。

If this is your only application, you technically don't have to retain the NSString when you get it from the accessor.

如果这是您唯一的应用程序,从技术上讲,从访问者那里获取NSString时不必保留NSString。

NSString * articleTitle = article.title;
label.text = articleTitle;
articleTitle = nil;

The UILabel will store a retained copy of the string when its 'text' property is set. You can 'nil' the reference after setting the text, and you'll get the same result. No extra retain/release involved. (Although it may be good practice)

UILabel将在设置“text”属性时存储字符串的保留副本。设置文本后,您可以“nil”引用,您将获得相同的结果。不涉及额外的保留/释放。 (虽然这可能是一个好习惯)