2010-02-17 32 views
7

我是新来的目标c,并试图了解如何/何时autorelease被称为。我理解的简单的例子:这个未来情况返回autorelease目标c中的错误?

- (void) foo { 
    Bar *b = [[[Bar alloc] init] autorelease]; 
    [self doSomething:b]; 
    } 

什么 - 这是一个错误,因为该对象将在离开makeBar的范围立即释放?

-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

如果调用者做了保留怎么办?

Bar *b = [[self makeBar] retain]; 

感谢, -Eric

+1

这个问题的内容和下面的两个答案应该在ObjC – ckhan

回答

7

在你的第二个例子,您传回匿名对象将不尽快执行叶makeBar但在运行的下一次迭代的范围公布循环。这将使你在任何方法的机会,retain它称为makeBar

所以,你的最后一个例子是确定的,因为保留计数不会低于0

你用起来麻烦吗?

+1

的新增内容的必读列表上。更具体的说,当它被添加到的自动释放池被排空/释放时,它将被释放。这通常是在运行循环结束时,但并非总是如此。 – dreamlax

+0

没有问题,我刚刚扫描我的代码以查找潜在的内存问题,并从我已复制的示例代码中看到该模式,并且不确定它是否为错误。 – esilver

5
-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

的第二情况下是返回一个Objective-C的对象优选方式。除了+alloc-copy...-create...,该方法应保留没有返回对象的所有权,即(的变化)保留计数应为0。

然而,[[Bar alloc] init]使对象为具有1 retainCount,一个应在返回之前释放它。但是-release会立即释放对象,使得该方法无用。这就是为什么使用-autorelease - 这是一个延迟-release,即对象将最终被释放,但不是现在,所以其他部分的代码仍然可以与它交互,但保留计数仍可以平衡到0.


Bar *b = [[self makeBar] retain]; 

你应该保留它除非你想成为的对象b的长期所有者。