1

Я новичок в Objective C, и я переношу части старой (не ARC) рамки в ARC. Мой вопрос заключается в том, что, несмотря на то, что ARC теперь обрабатывает много управления памятью за кулисами, существуют ли какие-либо основные принципы управления памятью, о которых я все еще должен знать, чтобы избежать утечек?Objective C Управление памятью с ARC

Например, я думал, что где-то я читал, что в «основной» функции подкласса NSOperation программист должен настроить «autoreleasepool» для этой функции.

+1

В моей книге перечислены некоторые распространенные ошибки: http://www.apeth.com/iOSBook/ch12.html#_unusual_memory_management_situations (раздел о необычных ситуациях управления памятью и примечание также предшествующего раздела о циклах сохранения) – matt

+0

Я не согласен с двумя «слишком широкие» близкие голоса, хотя это действительно может быть дубликат. –

+0

Вопросы, требующие такого рода «подводных камней» или «особенностей» информации [не очень хорошо работают при переполнении стека] (http://meta.stackexchange.com/a/76492/159251); ни один ответ не может быть окончательным и полным. Мы [в конечном итоге со списком одинаково допустимых] (http://meta.stackexchange.com/a/56773/159251) сообщений в стиле форума, а не одно, что нужно прочитать, которое может поддаться проверке на проблему. Таким образом, «слишком широкий». @JasperBlues –

ответ

1

Программист по-прежнему должен быть осведомлен о сохранении/освобождении на 100%, однако компилятор выполняет 98% работы. 2%, которые он не может преуспеть, - это разрыв цикла сохранения, поэтому компилятору полезно указать слабое сохранение в свойствах или использование модификатора __weak в выбранных сценариях.

Вы все еще можете настроить свой собственный @ autoreleasepool. Единственный раз, когда я использовал их целенаправленно, находится в/в качестве тела цикла for, чтобы заставить память исправлять каждую итерацию.

2

Вероятно, две самые большие проблемы для наблюдения: 1) сохранить циклы, где x сохраняет y и y сохраняет x, таким образом, они никогда не освобождаются. Обычно это происходит с блоками. И 2) при использовании функций Core Foundation (Core Graphics и т. Д.), Например: CGImageCreate, CGImageRetain, CGImageRelease. В этих случаях вам все равно нужно вручную управлять памятью.

Обычный шаблон для предотвращения циклов удержания - это создание слабой ссылки на один из объектов, которые были бы в цикле. (Часто сам). Такие, как это:

__weak typeof(self) weakSelf = self; 
[self useBlock:^{ 
    typeof(weakSelf) strongSelf = weakSelf; 
    // do something with strongSelf 
}]; 

Примечание: а) Причина вы хотите создать новый strongSelf внутри блока, чтобы гарантировать, что Вы сохранить переменную weakSelf для длительности блока. В противном случае, вы можете иметь случаи, когда weakSelf станет ноль частью через блок. В некоторых случаях вам может потребоваться добавить тест, который strongSelf все еще существует немедленно, и если не полностью отменить блок. Поскольку weakSelf может стать nil до начала блока.

__weak typeof(self) weakSelf = self; 
[self useBlock:^{ 
    typeof(weakSelf) strongSelf = weakSelf; 
    if (!strongSelf) return; 
    // do something with strongSelf 
}]; 

б) Вы должны сделать это, когда сам будет удерживать блок (в данном случае с помощью чего-то неизвестный метод useBlock делает) только.

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