【问题标题】:Objective-C Accessor Methods and Use of AutoreleaseObjective-C 访问器方法和 Autorelease 的使用
【发布时间】:2026-01-05 13:25:01
【问题描述】:

我一直在阅读有关内存管理的苹果文档,现在对推荐的访问器实现有点困惑。 Apple 引用了 3 种实现访问器的方法。

技巧1

我从第一种技术中复制了代码,该技术反映:“Getter 在返回值之前保留并自动释放该值;setter 释放旧值并保留(或复制)新值。”第一种技术据说更健壮,但在频繁调用的 getter 上会受到性能损失。

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

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

跳跃技巧2

技巧3

第三种技术更适合经常调用的 setter 和 getter。这也是我一直遵循的方法。

- (NSString*) title {
    return title;
}

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

我的问题是:

  1. (技术 1)setter 首先释放现有值,即使它没有指向任何东西。这将向 nil 发送一条消息,据我所知,Objective-C 支持该消息,但看起来仍然很奇怪。我理解正确吗?

  2. (技术 1)为什么要在自动释放中堆叠保留?

  3. (技术 1)使用 getter 的调用者是否应该在对象完成后调用 release?

苹果开发者文档页面位于:Memory Management Programming Guide - Accessor Methods

【问题讨论】:

  • 技巧4:使用合成属性。标准合成属性大致相当于技术 1,但也具有互斥锁,nonatomic 合成属性相当于技术 3。

标签: objective-c memory-management accessor


【解决方案1】:

(技巧一)二传手优先 释放现有值,即使它 没有指向任何东西。这个会 向 nil 发送消息,我 在 Objective-C 中支持理解 但看起来仍然很奇怪。我是吗 理解正确吗?

是的。发给nil 的消息无关紧要。

(技巧一)为什么要retain 堆叠在自动释放器中?

这保证以下内容不会中断:

x = [foo title];
[foo setTitle: @"bar"];
[x length]; // x has been released, possibly, if -title didn't retain/autorelease

(技巧一)是调用者使用 期望调用释放的吸气剂 在他们处理完对象之后?

没有。


【讨论】:

    【解决方案2】:
    1. 向 nil 发送消息被定义为什么都不做。这个 setter 是一个很好的例子,它可以让你编写更简单的代码:[title release] 而不是 if (title != nil) [title release];。另请注意,在 newTitle 上不需要对 nil 进行特殊检查。

    2. getter 中的保留/自动释放对意味着返回的对象将在当前函数调用的整个生命周期内保持有效(从技术上讲,直到自动释放池耗尽),即使调用了 setter。您引用的文档提供了一个示例,说明如果存在对值具有“非拥有引用”的变量,这将如何发挥作用。

    3. 没有。该值已经被自动释放;调用者不得再次释放它。

    【讨论】:

      最近更新 更多