2012-04-12 4 views
21

Это хорошая практика, чтобы положить много autoreleased объект в autoreleasepool при действии петли. Я нашел, что кто-то поставил @autoreleasepool в цикле, а другие поставили цикл в @autoreleasepool.@autoreleasepool в цикле или петле в @autoreleasepool?

1:

while ([rs next]) { 
    @autoreleasepool { 
     NSDictionary *dict = [self dictFromXX]; 
     //... 
    } 
} 

2:

@autoreleasepool { 
    while ([rs next]) { 
     NSDictionary *dict = [self dictFromXX]; 
     //... 
    } 
} 

Что лучше? или какой-либо разницы между кодом 1 и 2?

Спасибо!

+0

Loop должен быть внутри autoreleasepool 2. правильно – Charan

+0

Посмотрите на [Управление памятью с Objective C/Cocoa/iPhone] (http://memo.tv/archive/memory_management_with_objective_c_cocoa_iphone). –

ответ

28

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

Второй пример будет только сливать бассейн один раз после цикла.

Итак, если внутренности петли вызывают раздувание памяти, переходите к варианту один. Если раздутие памяти по всему циклу приемлемо, тогда используйте цикл 2.

1

Я хотел бы пойти на версии 2.

@autoreleasepool блок освободит все объекты, получившие autorelease, когда блок был закончен. Это потребует времени, потому что ему понадобятся некоторые циклы процессора и в зависимости от объекта, используемое время может быть намного выше ожидаемого.

Я думаю, что пользовательский @autoreleasepool s имеет смысл только при работе со многими данными> 20 МБ или работе с данными в не основной теме.

So. Я рекомендую избегать «коротких» @autoreleasepool. Потому что это может замедлить выполнение.

+0

Я не понимаю, общий цикл ЦП для выпуска будет таким же, потому что в итоге общий объект, который будет выпущен, будет таким же. Вы говорите о накладных расходах на выполнение проверки пула авторезистов? Я не уверен, что там наверху. –

+0

@ HelinWang слишком много сбрасывает память, что означает растрачивание циклов процессора на NSAutoreleasePool. – Andy

+0

@ Энди, это то, что мой комментарий спрашивает: почему он слишком часто истощает память? --- «в итоге общий объект, который будет выпущен, будет таким же» –

3

В первом примере autoreleasepool создается в начале итерации и сливается и заканчивается итерация. Во втором случае пул создается один раз и уничтожается только после завершения цикла. Если вы используете второй вариант, вы можете получить большие накладные расходы памяти, так как все автореализованные объекты освобождаются только в конце. Однако вы должны рассмотреть объем данных, который вам нужно обработать. В большинстве случаев предпочтительнее второй вариант.

0

В зависимости от того, сколько отложенных предметов будет выпущено. Изображение, что Autorelease Pool, как ваш мусор, положить неиспользованные вещи и бросить позже.

0

@autoreleasepool блоки эффективнее, чем при использовании экземпляра NSAutoreleasePool; вы также можете использовать их, даже если вы не используете ARC.- NSAutoreleasePool Class Reference

Вы вообще не нужны autorelease бассейны, если вы делаете, потому что вы в цикле и autoreleasing много объектов, то вариант 1 имеет больше смысла, чем 2, как вы пытаетесь избежать всплеска, что петля является Создание. Время использования опции 2 заключается в том, что нет пула авторезистов (если вы выполняете селектор в фоновом режиме, например, или в +load), но вы действительно должны попытаться использовать GCD для них в любом случае.

Таким образом, если у вас нет очень длинного метода, и вам нужно обернуть цикл в пуле автозапуска, в большинстве случаев перейдите к опции 1. Если метод вызывается без пула авторезистов, который был настроен, то @autorelease должен быть первым.

Смежные вопросы