什么时候触发自动释放池

Posted

技术标签:

【中文标题】什么时候触发自动释放池【英文标题】:When is the autorelease pool triggered 【发布时间】:2010-08-09 12:16:08 【问题描述】:

我在整个应用程序中都使用了 autorelease,并且想了解 autorelease 方法的行为。默认的自动释放池何时耗尽?它是基于计时器(每 30 秒?)还是必须手动调用?我需要做些什么来释放带有 autorelease 标记的变量吗?

【问题讨论】:

【参考方案1】:

在创建和发布时(我会说)有 3 个主要实例:

1. 应用程序生命周期的开始和结束,用 main.m 编写

int main(int argc, char *argv[])  
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    int retVal = UIApplicationMain(argc, argv, nil, nil); 
    [pool release]; 
    return retVal; 

2.每个事件的开始和结束(在 AppKit 中完成)

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
- (void)loadView 
/* etc etc initialization stuff... */
[pool release];

3.只要你想(你可以创建自己的池并释放它。[来自苹果内存管理文档])

– (id)findMatchingObject:anObject  
    id match = nil; 
    while (match == nil)  
        NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; 
        /* Do a search that creates a lot of temporary objects. */ 
        match = [self expensiveSearchForObject:anObject]; 
        if (match != nil)  
            [match retain]; /* Keep match around. */ 
         
        [subPool release]; 
     
    return [match autorelease];   /* Let match go and return it. */

【讨论】:

子线程呢?如果我们不明确创建池,默认行为是什么?【参考方案2】:

只要当前 run-loop 结束,它就会被耗尽。这就是当你的方法和调用你的方法的方法和调用那个方法的方法等等都完成的时候。

来自documentation:

Application Kit 在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在结束时将其排出,从而释放在处理事件时生成的所有自动释放对象

【讨论】:

每个外部事件都会触发一个运行循环的循环,例如鼠标事件、按键、异步 HTTP 连接上的数据接收等。还有 NSTimers,但曾经存在一个问题,即计时器使用稍微不同的代码路径,因此在收到真实事件之前不会耗尽自动释放池。现在可能已经解决了。

以上是关于什么时候触发自动释放池的主要内容,如果未能解决你的问题,请参考以下文章

29-oc自动释放池

自动释放池与垃圾收集有啥联系?

iOS自动释放池_原理_如何工作

iOS自动释放池_原理_如何工作

ios自动释放池

自动释放池