示例:
- (NSString*) title {
return [[title retain] autorelease];
}
设置器实际上已经保留了它,对吧?而且实际上没有人应该绕过Setter... 所以我想知道为什么getter不只是返回对象呢?它实际上已经被保留了。或者这只是在另一个对象在此期间传递到setter的情况下才需要吗?
示例:
- (NSString*) title {
return [[title retain] autorelease];
}
设置器实际上已经保留了它,对吧?而且实际上没有人应该绕过Setter... 所以我想知道为什么getter不只是返回对象呢?它实际上已经被保留了。或者这只是在另一个对象在此期间传递到setter的情况下才需要吗?
从这里 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将破坏现有的客户端代码...
这不仅适用于某人释放容器的情况,因为在那种情况下,他们应该自己保留对象更加明显。考虑以下代码:
NSString* newValue = @"new";
NSString* oldValue = [foo someStringValue];
[foo setSomeStringValue:newValue];
// Go on to do something with oldValue
这看起来很合理,但是如果setter和getter都没有使用autorelease,则“继续进行某些操作”部分很可能会崩溃,因为oldValue现在已被释放(假设没有其他人保留它)。您通常希望使用苹果公司的访问器方法示例中的技术1或技术2,以使像上面的代码一样的代码能够按照大多数人的预期工作。
比较以下代码
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!
在您的title
方法中,保留(并使用autorelease
而不是release
)可以防止代码崩溃。自动释放的对象将在当前调用栈执行完成后(当前运行循环结束时)才调用其release
方法。这为调用栈中的所有客户端代码提供了一个机会,以使用该对象,而不必担心它被解除分配。
需要记住的重要事情: 这不是Java、Ruby或PHP。仅仅因为您的变量中有一个对象的引用,并不能保证您不会在其下面得到它的dealloc。您必须对其进行保留,但 autorelease
可以让您避免这样做。除非您处理具有许多迭代的属性或循环(即使出现问题也可能不需要),否则您应该始终使用autorelease。
啊,好吧。从smorgan链接的文档中看来,这似乎是苹果目前推荐人们使用的方法之一。不过我还是更喜欢老式的版本:
- (NSString *) value
{
return myValue;
}
- (void) setValue: (NSString *) newValue
{
if (newValue != myValue)
{
[myValue autorelease]; // actually, I nearly always use 'release' here
myValue = [newValue retain];
}
}
[obj copy]
,那么你会在发送回来的 obj 上多一个 retain。谁会释放它呢?所以你最终会做 [[obj copy] autorelease]
,这是一样的。只返回 myValue
(老派版本)是安全的,直到它不安全,就像海平面发电机。 - Dan Rosenstark