Объектив-C (в первую очередь) использует модель памяти подсчета. Существует ручная подсчет ссылок и автоматический подсчет ссылок (ARC).
Как ARC Работает
Если вы когда-либо работали с ручным подсчетом ссылок и запустить лязг инструмент статического анализатора, вы увидите, что он делает удивительную работу по поиску утечек памяти. Это идея ARC - если анализатор может так хорошо найти утечки, то почему бы не позволить ему выполнять управление памятью?
Итак, анализ выполняется во время компиляции, а полученный код обрабатывается с помощью вызовов сохранения и освобождения. Это основа ARC и отличная модель памяти, обеспечивающая хороший баланс между производительностью и простотой использования. Его особенно полезно в мобильных вычислениях, потому что, в отличие от сбора мусора, он не потребует дополнительных циклов процессора или разряда батареи.
(NB: ARC также вводит слабые ссылки, что является способом обнуления оборванных указателей во время выполнения).
Использование ARC не так просто, как сбор мусора - вам все равно нужно знать, как работает модель подсчета памяти. Возможны следующие проблемы.
Сохранил Циклы
Основной причиной утечки памяти является сохранение цикла. Здесь объект A имеет ссылку на объект B, а объект B имеет ссылку на объект A. Например, AirlineFlight содержит пассажира, а пассажир имеет утечку памяти AirlineFlight ->.
Это очень распространено в Какао. Другим примером является ViewController, который имеет представление, а View имеет делегат, который является ViewController. Звучит знакомо?
Чтобы избежать цикла удержания, необходимо, чтобы один из объектов не оставил другого. Наиболее распространенный подход - обозначить его как родителя, а другой - как ребенка. Родитель сохраняет дочерний элемент, но ребенок не сохраняет родителя. Пример:
Просмотр Контроллер
@interface MyViewController
@property (nonatomic, strong) MyView* view
@end
Просмотр
@interface MyView
@property (nonatomic, assign) MyViewController* controller
@end
Сохранять цикл теперь сломаны и утечка памяти больше не будет возникать. не
висячие указатели
Приведенный выше пример больше не имеет утечку памяти, но может привести к другой проблеме - висячие указатели. Контроллер вида может исчезнуть, в то время как представление все еще имеет ссылку на контроллер. Любой вызов контроллера приведет к сбою.
Там два пути, чтобы исправить это:
Nil вне ссылку на контроллер в методе dealloc. , , но, вероятно, просто
Используйте слабую ссылку, следующим образом:
@property (nonatomic, weak) MyViewController* controller
ИОС 5 и выше (или OSX 10.7) имеют небольшую утилиту выполнения, которая отслеживает оборванными указателей и Nils их для вас - это называется слабыми ссылками.
Поиск памяти Утечки
Есть несколько способов.
- Используйте статический анализатор clang для определения циклов удержания.
- Инструмент «Инструменты»
- Мне нравится помещать операторы журнала в метод dealloc моих контроллеров и других классов ключей, чтобы обеспечить их освобождение.
Поиск висячие указатели
- Compile с переменной окружения NS_ZOMBIES_ENABLED (или изменить схему в Xcode и установите флажок, который будет установлен этот параметр для вас).
Авто-релиз бассейны
Другая проблема, которая может произойти слишком много объектов, которые выделяются в течение выполнения цикла. , Чтобы исправить это, вы можете создать еще один пул автоматического выпуска в основном пуле.
@autoreleasepool
{
}
(В вашем случае, я не думаю, что это проблема).
Почему вы уверены, что авария связана с утечкой памяти? – Gereon
Проверял его с монитором активности, всегда примерно до 420 МБ, из-за сбоя приложения, а не для его просмотра, и я получаю предупреждения о памяти. – Dim
, когда какой-либо вид вытащил стек навигации, он будет выпущен автоматически, если вы используете 'ARC'. ситуация, которую вы описали в своем вопросе, никогда не случится, если вы не сохраните объекты как-то, то есть указатели хранятся в другом массиве, и они сохраняют их и т. д. – holex