2011-11-16 53 views
2

在Objective-C手动上所记的东西像谁拥有autorelease对象?

return [[[SomeClass alloc] init] autorelease]; 

可以完成,然后release没有必要在任何时候,甚至在接收到该对象的功能。谁拥有这个对象呢?它何时会被释放?

回答

7

当前NSAutoreleasePool确实会在排水时处理释放。

IBAction调用被包装成NSAutoreleasePool,在调用之后被调用。

对于所有非IBAction为调用以下将适用:

说,你有这些方法:

- (id)foo { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    SomeClass *bar = [self bar]; //bar still exists here 
    //do other stuff 
    //bar still exists here 
    //do other stuff 
    //bar still exists here 
    [pool drain]; //bar gets released right here! 
    //bar has been released 
} 

- (id)bar { 
    return [[[SomeClass alloc] init] autorelease]; //bar will still be around after the return 
} 

考虑另一种情形:

- (void)foo { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    //do other stuff 
    [self bar]; 
    //do other stuff 
    [pool drain]; //the string from blee would be released right here; 
} 

- (void)bar { 
    [self baz]; 
} 

- (void)baz { 
    NSString *string = [self blee]; 
} 

- (id)blee { 
    return [NSString string]; //autoreleased 
} 

正如你可以看到自动释放字符串对象甚至不必用于或返回到创建池的范围。

NSAutoreleasePools堆栈(每线程)上存在和自动释放对象获得通过的最顶层,在调用autorelease时间的池拥有。


更新: 如果你正在处理一个紧密循环,并希望保持内存适度低,而不会减慢您的循环,可考虑做这样的事情:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
for (NSUInteger i = 0; i < 1000000000; i++) { 
    [NSString stringWithString:@"foo"]; 
    if (i % 1000 == 0) { 
     [pool drain]; 
     pool = [[NSAutoreleasePool alloc] init]; 
    } 
} 
[pool drain]; 

然而NSAutoreleasePool高度优化,所以每次迭代一个池通常不是一个问题。


要充分了解如何NSAutoreleasePools做工阅读本excellent article by Mike Ash

+0

当它倒掉? – Dani

+0

如果你明确地创建了它,当你调用[pool drain](最佳实践)时,或者池本身被释放时[pool release],它会被耗尽。如果你使用的隐式autorelease池,它由运行循环管理,原则上每次都会被清空。 – isaac

+0

@Dani:延长我的回答。现在应该更清楚了。 – Regexident