getter 方法中的保留和自动释放

发布于 2024-10-17 04:13:10 字数 217 浏览 6 评论 0原文

我正在学习内存管理,但我真的不明白为什么我应该像这样实现我的属性 getter:

-(Weapon*)myWeapon
{
    [myWeapon retain];
    [myWeapon autorelease];
    return myWeapon;
}

我理解我写的内容,但我无法想象为什么它很重要?你能解释一下为什么我应该这样做吗?

I am learning memory management, but I don't really understand why I should implement my attribute getter like this:

-(Weapon*)myWeapon
{
    [myWeapon retain];
    [myWeapon autorelease];
    return myWeapon;
}

I understand what I wrote, but I can't imagine why it is important? Can you please explain why I should do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞陪衬 2024-10-24 04:13:10

这是来自内存管理编程指南:

技术 1
在技​​术 1 中,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.
    }
}

因为从 get 访问器返回的对象在当前范围内自动释放,所以如果属性值发生更改,它仍然有效。这使得访问器更加健壮,但代价是额外的开销。如果您希望频繁调用 getter 方法,则保留和自动释放对象的额外成本可能不值得性能成本。

技巧2
与技术 1 一样,技术 2 也使用了自动释放技术,但这次是在 setter 方法中使用的:

- (NSString*) title {
    return title;
}

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

在调用 getter 的次数比调用 setter 的次数多的情况下,技术 2 的性能明显优于技术 1。

技巧3
技术 3 完全避免使用自动释放:

- (NSString*) title {
    return title;
}

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

技术 3 使用的方法适用于频繁调用的 getter 和 setter 方法。对于不想延长其值的生命周期的对象(例如集合类)也很有用。它的缺点是旧值可能会立即被释放(如果没有其他所有者),如果另一个对象维护对它的非拥有引用,这将导致问题。例如:

NSString *oldTitle = [anObject title];
[anObject setTitle:@"New Title"];
NSLog(@"Old title was: %@", oldTitle);

如果 anObject 是唯一拥有原始标题字符串的对象,则在设置新标题后,该字符串将被释放。然后日志语句将导致崩溃,因为 oldTitle 是一个已释放的对象。

编辑:基本上,保留然后自动释放的目的是确保如果在调用范围有机会保留它之前属性值发生更改,则该对象不会被释放。除非您有异步代码,否则这通常不是问题。在大多数情况下 - (Weapon *)myWeapon { return myWeapon; } 就可以了(而且速度更快)。

This is from the Memory Management Programming guide:

Technique 1
In technique 1, values returned by the getter are autoreleased within the calling scope:

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

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

Because the object returned from the get accessor is autoreleased in the current scope, it remains valid if the property value is changed. This makes the accessor more robust, but at the cost of additional overhead. If you expect your getter method to be called frequently, the added cost of retaining and autoreleasing the object may not be worth the performance cost.

Technique 2
Like technique 1, technique 2 also uses an autorelease technique, but this time does so in the setter method:

- (NSString*) title {
    return title;
}

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

The performance of technique 2 is significantly better than technique 1 in situations where the getter is called much more often than the setter.

Technique 3
Technique 3 avoids the use of autorelease altogether:

- (NSString*) title {
    return title;
}

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

The approach used by technique 3 is good for frequently called getter and setter methods. It is also good for objects that do not want to extend the lifetime of their values, such as collection classes. Its disadvantage is that the old value may be deallocated immediately (if there are no other owners), which will cause a problem if another object is maintaining a non-owning reference to it. For example:

NSString *oldTitle = [anObject title];
[anObject setTitle:@"New Title"];
NSLog(@"Old title was: %@", oldTitle);

If anObject was the only object that owned the original title string, then the string will be deallocated after the new title is set. The log statement would then cause a crash as oldTitle is a freed object.

EDIT: Basically the point of retaining and then auto-releasing is to ensure that the object won't get deallocated if the property value is changed before the calling scope has a chance to retain it. This isn't usually an issue unless you've got asynchronous code. In most situations - (Weapon *)myWeapon { return myWeapon; } is just fine (plus it's faster).

放低过去 2024-10-24 04:13:10

正如 ACBurk 所说,但这里有一个很好的描述:

http://vgable.com/blog/2009/03/31/how-to-write-cocoa-object-getters/

As ACBurk says, but there is a good description here:

http://vgable.com/blog/2009/03/31/how-to-write-cocoa-object-getters/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文