Что такое ARC и как он работает в Swift
Что проверяют
Понимаете ли вы, что ARC это подсчёт ссылок, расставленный компилятором, а не сборщик мусора, и знаете ли, где он ломается.
Как отвечать
ARC (Automatic Reference Counting) считает сильные ссылки на экземпляры классов. Retain и release расставляет компилятор при сборке, во время работы память никто не сканирует: счётчик дошёл до нуля, вызвался deinit, память освободилась сразу и предсказуемо.
Работает только для ссылочных типов. Структуры и перечисления копируются по значению, считать там нечего.
Три вида ссылок:
- strong, по умолчанию: держит объект;
- weak: не держит, обнуляется автоматически, поэтому всегда опциональна;
- unowned: не держит и не обнуляется. Обращение к освобождённому объекту это падение, зато без опционала.
Главная проблема это цикл сильных ссылок: два объекта держат друг друга, счётчик ни у одного не доходит до нуля, память не возвращается. Классический случай в замыканиях, где замыкание захватывает self, а self хранит замыкание. Лечится списком захвата:
request { [weak self] data in self?.render(data) }Где спотыкаются
Называют ARC сборщиком мусора. Разница принципиальная: у GC есть пауза и отдельный поток, у ARC нет ни того ни другого, зато он не умеет разрывать циклы.
Ставят unowned там, где объект может умереть раньше, и получают падение вместо nil.
Выбирают между weak и unowned наугад, хотя выбор по времени жизни: родитель переживает ребёнка это unowned, обратный случай weak.
Забывают, что делегат почти всегда weak, иначе контроллер и делегат держат друг друга.