这些内存管理技术在什么情况下更好?

4

苹果公司的内存管理编程指南展示了三种官方认可的编写需要保留或释放对象引用的访问器方法的技术。

在前两种技术的情况下(如下所述),苹果文档称:“在 getter 方法被调用次数远多于 setter 方法的情况下,技术2的性能明显优于技术1。”

// Technique 1
- (NSString*) title
{
    return [[title retain] autorelease];
}

- (void) setTitle: (NSString*) newTitle
{
    if (title != newTitle)
    {
        [title release];
        title = [newTitle retain]; // Or copy, depending on your needs.
    }
}

// Technique 2
- (NSString*) title
{
    return title;
}

- (void) setTitle: (NSString*) newTitle
{
    [title autorelease];
    title = [newTitle retain]; // Or copy, depending on your needs.
}

这两种技术的唯一区别是什么?如果使用其中一种而不是另一种,是否还有其他微妙的后果需要我注意?如果技术2使用更好的getter,那么技术1是否使用更好的setter,因为title会得到明确(并且可能是立即的)释放?
2个回答

1

来自2的getter和来自1的setter:

- (NSString*) title
{
    return title;
}

- (void) setTitle: (NSString*) newTitle
{
    if (title != newTitle)
    {
        [title release];
        title = [newTitle retain]; // Or copy, depending on your needs.
    }
}

0

第二个getter很脆弱(如果有人访问对象的title然后释放对象,它将崩溃),因此即使稍微慢一点,第一个getter通常更可取。

第一个setter更高效,即使在不存在自动释放池的情况下也可以工作,因此更可取。它更高效的原因不仅仅是因为自动释放与释放之间的区别 - 如果您尝试将属性设置为其现有值,则根本不会执行任何操作。


@ughoavgfhw:在dealloc中使用访问器是不合适的,实际上被苹果和大多数Cocoa程序员认为是一种不好的做法。 - Chuck
@chuck从技术1访问getter然后释放将同样导致崩溃。 - Remover
@Remover:由于保留,该保留计数应比技术2高一个。Autorelease不会立即释放对象,因此不会使其保留计数减少 - 它只是将其添加到autorelease池中。对象直到池被排放才会实际释放。因此,即使包含对象已释放,从技术1 getter返回的值仍将保留,直到autorelease池被排出(通常在事件循环的下一次迭代中)。因此,没有崩溃。 - Chuck
@Remover:我不知道这个“1 release message too many”是从哪里来的。我不是在谈论过度释放。我是在谈论一个对象的属性与对象一起被释放,即使该属性仍然在周围上下文中使用。例如:Foo *foo = [Foo new]; NSString *name = [foo name]; [foo release]; return [name stringByAppendingString:@" is my name"]; —— 使用getter 2会崩溃,但使用getter 1完全正常。 - Chuck
@chuck:啊哈!这就是所有这些可怕混乱的来源……那就搞清楚了。 - Remover
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接