处理Objective C中的无限循环

时间:2011-10-22 05:41:21

标签: objective-c ios memory-leaks

我最近加入了一个iPad项目。在查看代码库时,我遇到了一些不寻常的事情,其中​​之一就是这个(我已经对此进行了元编码):

while (something.isAlwaysTrue) {
    // Wait for something to happen. i.e. Get data from an internet connection.
    // Respond to something.
}

在我开始对应用程序进行内存分析之前,我没有发现任何问题,并发现这些循环是内存大量泄漏。原因是因为它们永远不会结束,所以在它们内部创建的任何autorelease实例都不会被释放,因为该方法永远不会结束,自动释放池永远不会有机会释放。

在与编写代码的开发人员讨论之后,我提出了以下技术:

-(void) queueTask {
    // Using GCD or perform with delay, call the process method.
}

-(void) process {

    // Wait and/or do stuff. 

    [self queueTask];
}

基本思想是通过使用方法对GCD或runloop进行排队,它为自动释放池提供了执行和清理autorelease实例的机会。这似乎工作正常。

我的问题是 - 这是处理这些循环的最佳方法吗?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:8)

两点;

尽量减少堆增长

无论如何,这是如何最大限度地减少内存增长:

while (something.isAlwaysTrue) {
  NSAutoreleasePool * pool = [NSAutoreleasePool new];
  // Wait for something to happen. i.e. Get data from an internet connection.
  // Respond to something.
  [pool release], pool = 0;
}

或者如果你更喜欢咩咩(sic)边缘:

while (something.isAlwaysTrue) {
  @autoreleasepool{
    // Wait for something to happen. i.e. Get data from an internet connection.
    // Respond to something.
  }
}

autorelease pool就像线程本地堆栈一样运行。当您推送池时,自动释放的对象将添加到当前线程的顶层池中。当您弹出池时,池会为每个自动释放发送一条release消息。

使用GCD代替自动释放池是奇怪的;类似于使用NSArray单个字符NSString,您应该只使用一个NSString

Mutithreaded Program Flow

无限循环是一个非常可疑的程序。它建议你可能正在尝试重新发明运行循环。主运行循环当然是常见的。具有永不结束的运行循环2)的辅助线程1)是不寻常的。

您应该重新考虑该计划的流程。通常情况下,你采取行动,而不是屏住呼吸,轮询直到完成。你可能试图在你提出的计划中摆脱这种情况 - 但我没有足够的细节。