@autoreleasepool в цикле или цикле в @autoreleasepool?
Это хорошая практика, чтобы положить много объектов autoreleased в autoreleasepool при выполнении цикла. Я нашел, что кто-то поставил @autoreleasepool в цикле, а другие поставили цикл в @autoreleasepool.
1
while ([rs next]) {
@autoreleasepool {
NSDictionary *dict = [self dictFromXX];
//...
}
}
2:
@autoreleasepool {
while ([rs next]) {
NSDictionary *dict = [self dictFromXX];
//...
}
}
Что лучше? или какая-либо разница между кодом 1 и 2?
Спасибо!
Ответы
Ответ 1
В вашем первом примере для каждой итерации пул сливается. Это имеет смысл, если тело итерации связано с множеством автореализованных объектов.
Второй пример будет только сливать пул один раз после цикла.
Итак, если внутренности цикла вызывают раздувание памяти, переходите к опции 1. Если раздутие памяти по всему циклу приемлемо, тогда используйте цикл 2.
Ответ 2
В первом примере autoreleasepool создается в начале итерации и сливается и заканчивается итерация.
Во втором случае пул создается один раз и уничтожается только после завершения цикла. Если вы используете второй вариант, вы можете получить большие накладные расходы памяти, так как все автореализованные объекты освобождаются только в конце. Однако вы должны рассмотреть объем данных, который вам нужно обработать. В большинстве случаев предпочтительнее второй вариант.
Ответ 3
Я бы пошел на версию 2.
Блок A @autoreleasepool
освободит все объекты, которые получили autorelease
, когда блок был закончен. Это потребует времени, потому что ему понадобятся некоторые циклы процессора и в зависимости от объекта, используемое время может быть намного выше ожидаемого.
Я думаю, что пользовательский @autoreleasepool
имеет смысл только при работе со многими данными > 20 МБ или работе с данными в не-основном потоке.
Итак. Я рекомендую избегать "коротких" @autoreleasepool
. Потому что это может замедлить выполнение.
Ответ 4
Вот другой подход с Core Data: autoreleasepools:
Тестирование основных данных с очень большими иерархическими наборами данных Эффективный импорт данных
Важным для вас является решение Wrap the contents of the outer loop in an NSAutoreleasePool init/release and NSManagedObjectContext save
.
Ответ 5
Зависит от того, сколько отложенных элементов будет выпущено. Изображение, что Autorelease Pool, как ваш мусор, положить неиспользованные вещи и бросить позже.
Ответ 6
Блоки @autoreleasepool
более эффективны, чем непосредственно с помощью экземпляра NSAutoreleasePool
; вы также можете использовать их, даже если вы не используете ARC. - Справка NSAutoreleasePool класса
Обычно вам не нужны пулы автозавершения, если вы это делаете, потому что вы находитесь в цикле и автореализовываете множество объектов, тогда вариант 1 имеет больше смысла, чем 2, поскольку вы пытаетесь избежать всплеска, который создает цикл. Время использования опции 2 - это если нет пула авторезистов (если вы выполняете селектор в фоновом режиме, например, или в +load
), но вы действительно должны пытаться использовать GCD для них.
В общем, если у вас нет очень длинного метода, и вам нужно обернуть цикл в пуле авторесурсов, перейдите для варианта 1 в большинстве случаев. Если метод вызывается без установленного пула автозаполнения, то @autorelease
должен быть первым.