辅助NSThread runloop中需要自动释放池的位置在哪里?

时间:2009-07-20 03:26:17

标签: iphone objective-c multithreading autorelease

我的应用程序的辅助线程的运行循环如下。 它有一个嵌套的控制循环。

  • 外部循环在应用程序的持续时间内运行
  • 内部循环在一个视图打开时运行,然后线程在视图未打开时等待。
  • 穿过内环很短,只有几分之一秒。

我的代码不会故意在未发布的池中留下任何自动释放的对象,但我不知道操作系统在做什么。

在主线程中,cocoa在每次遍历运行循环时都会自动释放一个自动释放池 在这个辅助线程中,我认为最接近的等价物是通过内循环。

内部自动释放池将每次传递包裹在内部循环中。

中间池环绕内部循环,因此在应用程序终止之前,不会保留在此级别创建和自动释放的对象。

外部池包装整个runloop。

如何确定所有这些池的创建和发布对我的代码速度有何影响。
如何确定所有三个池是否必要或是否过度?




代码和解释:

- (void)processLoop
{

    NSAutoreleasePool * outerPool = [[NSAutoreleasePool alloc] init];
    [processCondition lock];

    //outer loop    
    //this loop runs until my application exits
    while (![[NSThread currentThread] isCancelled])    
    {
        NSAutoreleasePool *middlePool = [[NSAutoreleasePool alloc];
        if(processGo)
        {
            //inner loop
            //this loop runs typically for a few seconds
            while (processGo && ![[NSThread currentThread] isCancelled]) 
            {
                NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc]; init];
                //within inner loop
                //this takes a fraction of a second
                [self doSomething];
                [innerPool release];
            }
            [self tidyThingsUp];

        }
        else
        {
            [processCondition wait];
        } 
        [middlePool release];
    }
    [processCondition unlock];
    [outerPool release];
}

组合:

  • 内在的循环
  • NSCondition * processCondition
  • processGoYES
  • 之间切换NO

允许我在不取消线程的情况下停止并启动内部while循环。

if (processGo == YES)


执行进入内部while循环。

当主线程设置

processGo = NO

执行离开内部while循环并整理
在外循环的下一次传递中,执行命中

[processCondition wait]

并等待

如果主线程重置

processGo == YES

并致电

[processCondition wait]

执行重新进入内循环

2 个答案:

答案 0 :(得分:5)

我真的不能给太多确定答案而不了解其中一些方法的作用,但是应用自动释放池时的重大问题与每个池处理的对象数量有关

有一个有趣的blog post,它会查看额外的自动释放池对创建和销毁一百万个NSObject实例的影响。帖子的要点是“自动释放池很便宜”:程序继续提高效率,每个池的对象更少,直到10个对象/ 1池比率。 (之后它会飞速发展,因为你在为每个对象创建一个池时快速关闭,这显然是愚蠢的。)

你要做的最好的事情是弄清楚每个发布池将要处理的对象数量。例如,如果你的内部池每次传递处理一百个对象,并且有一百个传递,那么摆脱该池将向中间池添加一万个对象 - 这将是一件坏事。另一方面,如果内部池处理一个对象,每个对象传递十次,那么确定,继续并去除它。

如果您无法做出决定,请查看是否可以找到一种方法来计算内部循环的性能或仅在中间池范围内执行的代码,然后根据需要添加/删除自动释放池。请记住:自动释放池很便宜。

答案 1 :(得分:1)

  

我如何确定是否全部三个   游泳池是必要的还是过度的?

您可以简单地评论一些池,​​看看应用程序内存会发生什么。

  

我怎样才能确定效果   创造和释放所有这些   游泳池有我的速度   代码。

我正在游戏的主循环中创建并发布自动释放池,它运行得非常好。没有打嗝,几乎没有时间。