Работа с бесконечными циклами в Objective C - PullRequest
5 голосов
/ 22 октября 2011

Я недавно присоединился к проекту 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 Ответ

8 голосов
/ 22 октября 2011

Две точки;

Минимизация роста кучи

в любом случае, вот как минимизировать рост памяти:

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.
  }
}

пулы с автоматическим выпуском просто работают как локальные стеки потоков. когда вы выдвигаете пул, автоматически высвобождаемые объекты добавляются в верхний пул в текущем потоке. когда вы извлекаете пул, пул отправляет сообщение release для каждого автоматического выпуска.

использование GCD в качестве заменителя пула авто-релиза является странным; аналогично использованию NSArray одного символа NSString s, где вы должны просто использовать один NSString.

поток многопоточных программ

бесконечный цикл - очень подозрительная программа. это предполагает, что вы, возможно, пытаетесь заново изобрести циклы выполнения. основной цикл выполнения, конечно, распространен. вторичный поток 1) с циклом выполнения 2), который никогда не заканчивается, является необычным.

вам следует пересмотреть ход программы. как правило, вы действуете на события, а не затаив дыхание, опрашивая, пока они не завершатся. возможно, вы пытаетесь выйти из этой ситуации в предложенной вами программе, но мне не хватает деталей.

...