Вопрос

Я создаю приложение для 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.

Это было полезно?

Решение

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

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

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

Другие советы

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

  • Вопрос:NSAutoreleasePool переносит методы?
  • А:Это зависит:
    1. Да, среди вложенных вызовов.
    2. В родственных вызовах нет.

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

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

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

РЕДАКТИРОВАТЬ:

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top