【问题标题】:where are autorelease pools required in a secondary NSThread runloop?辅助 NSThread 运行循环中需要自动释放池在哪里?
【发布时间】:2010-11-12 04:52:27
【问题描述】:

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

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

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

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

inner 自动释放池通过内部循环包装每个通道。

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

外部池包裹了整个运行循环。

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




代码及说明:

- (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];
}

组合:

  • 内部 while 循环
  • NSCondition *processCondition
  • YESNO 之间切换processGo

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

if (processGo == YES)


执行进入内部while循环。

当主线程设置时

processGo = NO

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

[processCondition wait]

等待

如果主线程重置

processGo == YES

并调用

[processCondition wait]

执行重新进入内循环

【问题讨论】:

    标签: iphone objective-c multithreading autorelease


    【解决方案1】:

    如果不了解其中一些方法的作用,我真的无法给出明确的答案,但应用自动释放池时最大的问题与每个池处理的对象数量有关.

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

    最好的办法是大致计算出每个释放池要处理的对象数量。例如,如果您的内部池每次通过处理一百个对象,并且有一百个通过,那么摆脱该池将向中间池添加一万个对象 - 这将是一件坏事。另一方面,如果内部池处理一个对象,每次传递十遍,那么当然,继续处理它。

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

    【讨论】:

      【解决方案2】:

      我怎样才能确定这三个 游泳池是必要的还是矫枉过正?

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

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

      我正在游戏的主循环中创建和释放一个自动释放池,它运行得非常好。没有打嗝,几乎不需要时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        • 2019-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-01
        相关资源
        最近更新 更多