NSAutoreleasePool переносится через методы? - PullRequest
1 голос
/ 18 июня 2009

Я создаю приложение для iPhone, где отсоединяю некоторые потоки, чтобы выполнять длительную работу в фоновом режиме, чтобы не зависать пользовательский интерфейс. Я понимаю, что потоки нуждаются в экземплярах 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 ]

7 голосов
/ 18 июня 2009

Чтобы ответить на ваш вопрос, да, другой метод использует NSAutoreleasePool, созданный вами в threadadedMethod, и все, что вы автоматически выпускаете, будет выпущено при освобождении / сливе aPool.

Таким образом, маловероятно, что ваша ошибка проистекает непосредственно из этого кода (если только это не происходит).

Поставьте точку останова на _NSAutoreleaseNoPool (добавьте его по имени в окне точек останова) и запустите свой код в отладчике, и он остановится, когда автозапуск вызывается без пула, и это должно решить вашу проблему.

0 голосов
/ 12 мая 2010

В вашем примере, да, NSAutoreleasePool переносит методы, поскольку вызов [self anotherMethod] вложен внутрь - (void)threadedMethod.

  • Q: NSAutoreleasePool, переносящий через методы?
  • A: Это зависит от:
    1. Через вложенные вызовы, да.
    2. Через одноуровневых заклинаний, нет.

И, несмотря ни на что, сам экземпляр NSAutoreleasePool выходит из области видимости, когда родительская область исчезает. - в вашем примере, в самом конце -(void)threadedMethod { }.

В статье, упомянутой ранее (http://thegothicparty.com/dev/macos/nsautoreleasepool/), об этом совершенно ясно.

0 голосов
/ 18 июня 2009

Пул авторелизов переносится на другой метод. Однако, когда ваша многопоточная функция заканчивается, вы должны вызвать [aPool release] вместо [aPool сток]. Они примерно эквивалентны, но выпуск aPool заставляет NSAutoreleasePool высвобождать себя в дополнение ко всем другим объектам в пуле. Когда ваша многопоточная функция заканчивается после вызова дампа, пул авто-релиза все еще имеет счет сохранения +1! Скорее всего, «просто подтекающий» объект - aPool!

EDIT:

Джим Пулс прав в том, что выпуск и слив эквивалентны. В документах Apple четко сказано, что они идентичны в среде без сбора мусора, а в случае с сборкой мусора расход лучше. Я виноват в том, что не читал документы!

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

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

...