处理Objective C中的无限循环

dre*_*kka 5 memory-leaks objective-c ios

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

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

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

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

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

-(void) process {

    // Wait and/or do stuff. 

    [self queueTask];
}
Run Code Online (Sandbox Code Playgroud)

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

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

jus*_*tin 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

多线程程序流程

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

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

  • 非常正确.我建议@autoreleasepool,然后如果你切换到ARC那个方法就准备好了. (2认同)
  • "屏住呼吸"好! (2认同)