NSAutoreleasePool переносит методы?
-
06-07-2019 - |
Вопрос
Я создаю приложение для 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 переносит методы?
- А:Это зависит:
- Да, среди вложенных вызовов.
- В родственных вызовах нет.
И несмотря ни на что, NSAutoreleasePool
сам экземпляр выходит из области видимости, когда родительская область видимости исчезает. -в вашем примере в самом конце -(void)threadedMethod { }
.
В упомянутой выше статье (http://thegothicparty.com/dev/macos/nsautoreleasepool/) об этом совершенно ясно.
Пул автоматического выпуска переносится на другой метод.Однако, когда ваша потоковая функция завершается, вам следует вызвать [aPool Release] вместо [aPool Drain].Они примерно эквивалентны, но выпуск пула приводит к тому, что NSAutoreleasePool освобождает себя в дополнение ко всем другим объектам в пуле.Когда ваша потоковая функция завершается после вызова дренажа, пул автовыпуска по-прежнему имеет счетчик сохранения +1!Скорее всего, «просто протекший» объект — это пул!
РЕДАКТИРОВАТЬ:
Джим Пулс прав в том, что освобождение и опустошение эквивалентны.В документах Apple четко сказано, что они идентичны в среде без сбора мусора, а слив лучше в случае со сборкой мусора.Моя вина, что не читал документацию!
Вот статья, в которой представлен общий обзор NSAutoreleasePools — она должна помочь вам указать правильное направление.Поскольку существует виртуальный стек пулов автоматического выпуска, самый верхний из них будет использоваться повсюду в вашем приложении — независимо от того, где объекты автоматически выпускаются.