代码之家  ›  专栏  ›  技术社区  ›  Tim

NSAutoReleasePool采用了多种方法?

  •  1
  • Tim  · 技术社区  · 15 年前

    我正在构建一个iPhone应用程序,在那里我分离一些线程来在后台执行长时间运行的工作,以避免挂起UI。我了解线程需要NSautoReleasePool实例来进行内存管理。我不确定的是线程方法是否调用另一个方法-该方法是否还需要NSautoReleasePool?

    示例代码:

    - (void)primaryMethod {
        [self performSelectorInBackground:@selector(threadedMethod) withObject:nil];
    }
    
    - (void)threadedMethod {
        NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];
    
        // Some code here
    
        [self anotherMethod];
    
        // Maybe more code here
    
        [aPool drain];
    }
    
    - (void)anotherMethod {
        // More code here
    }

    我问的原因是我接收到了一些错误,这些错误是对象在没有池的情况下自动释放,并且“只是泄漏”。

    我还看到过其他问题,人们根本没有自动租赁池,我理解为什么需要自动租赁池。我特别想知道是否在中创建了自动释放池(在本例中) threadedMethod 应用于在中创建的对象 anotherMethod .

    3 回复  |  直到 14 年前
        1
  •  7
  •   Peter N Lewis    15 年前

    要回答您的问题,是的,另一种方法是使用您在threadedmethod中创建的nsautoreleasepool,当apool释放/排出时,您自动释放的任何内容都将被释放。

    因此,您的错误不太可能直接源于此代码(除非有更多的情况发生)。

    在nsautoreleasenopool上放置一个断点(在断点窗口中按名称添加),然后在调试器中运行代码,当在没有池的情况下调用autorelease时,它将停止,这样可以解决您的问题。

        2
  •  0
  •   SwiftArchitect    14 年前

    在您的示例中,是的,自从调用 [self anotherMethod] 嵌套在内部- (void)threadedMethod .

    • 问:NSAutoReleasePool采用了多种方法?
    • 答:要看情况:
      1. 跨嵌套调用,是的。
      2. 跨兄弟调用,不。

    不管怎样, NSAutoreleasePool 当父作用域消失时,实例本身就超出作用域。 -在您的示例中,在 -(void)threadedMethod { } .

    前面提到的文章( http://thegothicparty.com/dev/macos/nsautoreleasepool/ )很清楚。

        3
  •  -1
  •   Ben Gotow Dmitry Nogin    15 年前

    自动释放池会传递到另一个方法。但是,当线程函数结束时,应该调用[apool release]而不是[apool drain]。它们大致相当,但apool的释放会使nsautoreleasepool释放自身以及池中的所有其他对象。当线程函数在调用drain之后结束时,自动释放池的保留计数仍然为+1!很可能,“刚刚泄漏”的物体是apool!

    编辑:

    Jim Puls认为释放和排放是等效的。苹果文档清楚地说,它们在非垃圾收集环境中是相同的,而在垃圾收集情况下,排水更好。我不看医生的过错!

    这篇文章概括介绍了NSAutoReleasePools——它将帮助您找到正确的方向。由于存在一个自动释放池的虚拟堆栈,所以应用程序中的任何地方都将使用最顶层的池,而不管对象在何处自动释放。

    http://thegothicparty.com/dev/macos/nsautoreleasepool/