Подтвердить что ты не робот

В ARC, по-прежнему целесообразно создавать @autoreleasepool для циклов?

Скажем, что у меня есть цикл, который возвращает кучу объектов с автореализованной NSData...

NSData* bigData = ...
while(some condition) {
    NSData* smallData = [bigData subdataWithRange:...];
    //process smallData
}

В ARC, должен ли я все-таки обернуть @autoreleasepool вокруг условия while?

NSData* bigData = ...
@autoreleasepool {
    while(some condition) {
        NSData* smallData = [bigData subdataWithRange:...];
        //process smallData
    }
}

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

Лучше ли использовать методы initWith..., когда это возможно?

4b9b3361

Ответ 1

Да, вы должны использовать пулы автозапуска при использовании удобных методов в узком цикле. Все старые правила управления памятью все еще применяются в ARC, компилятор просто вводит RR для вас. Оформить замечательный пост от удивительного Майка Эша!

Ссылка

Ответ 2

Я думаю, что ваша проблема заключается в том, что пул авторесурсов должен пройти внутри цикла. С петлей внутри блока авторекламы, а не наоборот, накопленные объекты не будут выпущены до завершения цикла.

Ответ 3

В ARC, должен ли я по-прежнему переносить @autoreleasepool вокруг условия while?

Да. Пулы Autorelease все еще на месте, и они растут и появляются по-прежнему. Компилятор просто добавляет и объединяет необходимые операции сохранения и освобождения при включенном ARC (эхо-вызове Logan) на основе методов, которые видны для TU и соглашений об именах по умолчанию.

Выполнение в ARC почти идентично подсчету ручной ссылки: стеки пулов Autorelease все еще существуют. Одно из отличий заключается в том, что компилятор может упорядочить операции подсчета ссылок, немного отличающиеся от того, как вы его написали (не ошибочно), и может опустить ненужные циклы сохранения.

Лучше ли использовать методы initWith... когда это возможно?

WRT минимизирует рост кучи по сравнению с автореализованными аналогами: Да. Это всегда было так. Это особенно важно на устройствах iOS, где память довольно ограничена.

Исключением является то, что объект может избежать выделения. Пример:

NSString * copy = [NSString stringWithString:arg];

в этом случае copy может быть [[arg retain] autorelease]. Обратите внимание, что в этом случае copy все еще автореализован, но вы не должны, как правило, идти на большие длины, чтобы проверить наличие таких оптимизаций. Примечание. Здесь также лучше использовать copy = [arg copy]... [arg release].

Другой бонус заключается в том, что ваш дисбаланс ref count часто улавливается ранее, когда объект никогда не автореализован, и ближе к сайту вызова (а не к тому, когда наконец будет добавлен пул Autorelease).

Производительность с большими пулами авторекламы на самом деле намного хуже, чем предполагалось большинством людей. Если вы можете в значительной степени избежать значительных изменений (например, используя alloc + init... + release), вы можете сделать вашу программу заметно быстрее. Явное создание пулов автоопределения дешево и может помочь свести к минимуму эту проблему. Когда распределения значительны и/или многочисленны, избегайте использования autorelease на них, где это возможно, и оберните эти разделы в явные пулы автозавершения.