Ответ
Основные инструменты — Instruments (Allocations и Leaks) и ручная проверка retain cycles.
1. Инструмент Allocations
Запуск: Product > Profile > Allocations в Xcode.
- Фильтруйте по именам своих классов.
- Наблюдайте за ростом счетчика #Persistent или #All.
- Ищите объекты, которые не освобождаются после ожидаемых событий (например, после dismiss контроллера).
- Используйте Mark Generation (кнопка внизу) для создания контрольных точек и отслеживания объектов, созданных между ними.
2. Инструмент Leaks
Запуск: Product > Profile > Leaks.
- Прямо показывает утечки — объекты, на которые больше нет сильных ссылок, но память не освобождена.
- Часто указывает на проблемы с C-кодом (Core Foundation, необработанные указатели).
3. Ручная проверка retain cycles
- Проверка вызова
deinit:class MyViewController: UIViewController { deinit { print("MyViewController deallocated") // Если не печатается — есть цикл } } - Типичные источники циклов:
- Замыкания: Всегда используйте
[weak self]или[unowned self], когдаselfудерживает замыкание. - Делегаты: Должны быть объявлены как
weak. - Таймеры:
Timerсильно ссылается на target. Используйте блоки или инвалидируйте вdeinit. - Уведомления (NotificationCenter): Не забывайте удалять наблюдателей.
- Замыкания: Всегда используйте
- Косвенный анализ: Используйте Debug Memory Graph (кнопка в Xcode) для визуализации графа объектов в конкретный момент времени и поиска неожиданных сильных ссылок.
Ответ 18+ 🔞
А, ну так, слушай, смотри, вот ты тут сидишь и думаешь: «Блядь, куда память девается, как будто её кто-то жрёт?» Это, сука, классика. Ну ладно, не паникуй, сейчас разберёмся, как эту хитрую жопу поймать.
Вот тебе основные штуки, которые надо в глаза тыкать.
1. Инструмент Allocations — наш главный подследственный
Запускаешь: Product > Profile > Allocations в Xcode, и понеслась.
- Там сверху есть фильтр — вбиваешь туда имена своих классов, как будто ищешь иголку в стоге говна.
- Смотришь на колонки #Persistent или #All. Если число растёт, а должно падать — это, блядь, подозрительно. Например, закрыл контроллер, а он в памяти как будто прирос намертво.
- Есть там кнопочка Mark Generation внизу — это вообще огонь. Нажал в начале сценария (например, открыл экран), потом что-то сделал и закрыл, нажал ещё раз. И смотришь, какие новые объекты между этими «поколениями» застряли. Вот они, твои паразиты!
2. Инструмент Leaks — стукач прямой наводки
Запускаешь: Product > Profile > Leaks.
- Этот, блядь, сразу орёт, если нашёл утечку. Чаще всего он находит не наши, свифтовые циклы, а какую-нибудь старую шнягу на C, где указатели забыли отпустить. Но тоже полезно.
3. Ручная проверка — для тех, кто не доверяет автоматам
Тут уже самому надо мозги включать, а то так и будешь с утра до вечера на графики смотреть.
-
Проверка вызова
deinit— святое дело:class MyViewController: UIViewController { deinit { print("MyViewController deallocated") // Если эту надпись не видишь — всё, пиздец, он живёт вечно. Значит, кто-то его держит. } } -
Типичные грабли, на которые все наступают:
- Замыкания: Ну ёпта, классика ж! Забыл написать
[weak self]— и всё, приехали.selfдержит замыкание, замыкание держитself. Вечная любовь, блядь, в памяти. - Делегаты: Если объявил делегат как
strong— готовься к сюрпризам. Должен бытьweak, и точка. Иначе контроллеры друг друга как два мудака в обнимку и не отпустят. - Таймеры:
Timer— тот ещё пидарас шерстяной. Он target держит крепко. Не инвалидировал вdeinit— считай, подарил ему бессмертие. Либо переходи на таймер с closure-based API. - Уведомления (NotificationCenter): Подписался, а отписаться забыл. Типа «ой, да похуй, система сама почистит». Не почистит, блядь! Особенно если iOS версии старые. Удалил наблюдателя — спи спокойно.
- Замыкания: Ну ёпта, классика ж! Забыл написать
-
Косвенный анализ — для параноиков: Есть в Xcode кнопка Debug Memory Graph (паутинка). Тыкаешь в неё, когда приложение в нужном состоянии, и смотришь на граф объектов. Можно ткнуть в любой и увидеть, кто на него ссылается. Иногда находишь такие неожиданные связи, что волосы дыбом встают — «а ты чё, сука, здесь забыл?».
Вот и весь сказ. Сначала deinit проверь, потом Instruments запусти, а там уже смотри, что за мудак память просирает. Удачи, не проеби!