示例:
- (NSString*) title {
return [[title retain] autorelease];
}
setter实际上已经保留了它,对吧?实际上没有人应该绕过Setter ......所以我想知道为什么吸气剂不仅仅会返回物体?它实际上已经保留了下来。或者只是在同时将另一个对象传递给setter的情况下才需要它?
答案 0 :(得分:12)
从这里http://www.macosxguru.net/article.php?story=20030713184140267
- (id)getMyInstance
{
return myInstanceVar ;
}
或
- (id)getMyInstance
{
return [[myInstanceVar retain] autorelease] ;
}
有什么区别? 第二个允许调用者获取容器对象的实例变量,处理容器并继续使用实例变量,直到当前自动释放池的下一个版本,而不会受到间接生成的实例变量的释放的影响通过释放其容器:
aLocalVar = [aContainer getAnInstanceVar] ;
[aContainer release];
doSomething(aLocalVar);
如果以第一种形式实现“get”,您应该写:
aLocalVar = [[aContainer getAnInstanceVar] retain];
[aContainer release];
doSomething(aLocalVar);
[aLovalVar release];
第一种形式在代码执行速度方面更有效。 但是,如果你正在编写供其他人使用的框架,也许应该推荐第二个版本:它使使用你的框架的人们的生活变得更容易:他们不必过多考虑他们在做什么......; ) 如果您选择第一个样式版本,请在文档中清楚说明......无论您选择哪种方式,请记住从版本1更改为版本2是为客户端代码保存,从版本2返回到版本1将破坏现有客户端代码...
答案 1 :(得分:7)
这不仅适用于有人释放容器的情况,因为在这种情况下,他们应该更自然地保留对象。请考虑以下代码:
NSString* newValue = @"new";
NSString* oldValue = [foo someStringValue];
[foo setSomeStringValue:newValue];
// Go on to do something with oldValue
这看起来很合理,但如果setter和getter都没有使用自动释放,那么“继续做某事”部分可能会崩溃,因为oldValue现在已经被释放(假设没有其他人保留它)。您通常希望使用Apple's accessor method examples中的技术1或技术2,因此上述代码将像大多数人期望的那样工作。
答案 2 :(得分:3)
比较此代码
return [[title retain] release]; // releases immediately
用这个
return [[title retain] autorelease]; // releases at end of current run loop (or if autorelease pool is drained earlier)
第二个保证客户端将使用非释放对象。
这在这种情况下很有用(客户端代码):
NSString *thing = [obj title];
[obj setTitle:nil]; // here you could hit retainCount 0!
NSLog(@"Length %d", [thing length]); // here thing might be dealloced already!
autorelease
方法中保留(并使用release
代替title
)会阻止此代码爆炸。自动释放的对象不会有调用其release
方法,直到当前调用堆栈执行完毕(当前运行循环结束)。这使得调用堆栈中的所有客户端代码都有机会使用此对象,而不必担心它会被解除分类。
需要记住的重要事项:这不是Java,Ruby或PHP。仅仅因为你在yer [sic]变量中引用了一个对象并不能确保你不会从你的下面取消它。你必须保留它,但然后你必须记住发布它。 Autorelease让你避免这种情况。您应该始终使用autorelease,除非您处理具有多次迭代的属性或循环(除非出现问题,否则可能不会这样)。
答案 3 :(得分:0)
我以前没见过这种模式,但对我来说似乎毫无意义。我想如果客户端代码在父对象上调用“release”,则意图是保持返回值安全。它并没有真正伤害任何东西,但我怀疑这种情况经常出现在精心设计的图书馆中。
啊,好的。从smorgan链接的文档来看,这似乎是Apple目前推荐人们使用的方法之一。我想我还是喜欢老式的版本:
- (NSString *) value
{
return myValue;
}
- (void) setValue: (NSString *) newValue
{
if (newValue != myValue)
{
[myValue autorelease]; // actually, I nearly always use 'release' here
myValue = [newValue retain];
}
}