我一直在阅读有关内存管理的苹果文档,现在对于推荐的Accessors实现感到有些困惑。 Apple引用了3种实现访问器的方法。
技术1
我已经复制了第一种反映出来的技术的代码:“Getter在返回之前保留并自动释放值; setter释放旧值并保留(或复制)新值。”第一种技术被认为更加强大,但在经常被称为吸气剂方面受到性能损失。
- (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)即使不指向任何内容,setter也会首先释放现有值。这将向nil发送一条消息,我理解在Objective-C中支持但仍然看起来很奇怪。我能正确理解吗?
(技术1)为什么保留堆叠在自动释放内?
(技术1)使用getter的调用者是否在完成对象后调用release?
可以在以下位置找到apple developer文档页面:Memory Management Programming Guide - Accessor Methods
答案 0 :(得分:6)
(技术1)首先是设定者 即使它发布现有价值 不指向任何事情。这个会 向我发送消息给我 Objective-C支持理解 但看起来仍然很奇怪。我 正确理解这个?
烨。发送给nil
的邮件不重要。
(技术1)为什么保留 堆放在自动释放内?
这可以保证以下内容不会中断:
x = [foo title];
[foo setTitle: @"bar"];
[x length]; // x has been released, possibly, if -title didn't retain/autorelease
(技术1)是使用的来电者 吸气者应该打电话给释放 他们完成了对象之后?
没有
答案 1 :(得分:1)
将消息发送到nil定义为什么都不做。这个setter是一个很好的例子,它可以让你编写更简单的代码:[title release]
而不是if (title != nil) [title release];
。另请注意,newTitle
上无需对nil进行特殊检查。
getter中的retain / autorelease对意味着返回的对象将在当前函数调用的生命周期内保持有效(技术上,直到自动释放池耗尽),即使调用了setter也是如此。您引用的文档给出了一个示例,说明如果变量具有对该值的“非拥有引用”,该如何有用。
NO。该值已经自动释放;来电者不得再发布。