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

时间:2009-07-16 15:07:30

标签: objective-c memory-management properties

我有以下简单的课程:

@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

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

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

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

NSString *title=[article.title retain];

也许我懒得去保留我得到的地方。或者如果我需要在应用程序中进行数十次这样的操作。

我可以让getter返回副本吗?

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

3 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:1)

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

对于普通的NSString,由于它是不可变的,copyretain都做同样的事情 - 它们保留字符串并返回它。

答案 2 :(得分:1)

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

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

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

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

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