Зачем введен механизм side table (боковой таблицы) в ARC
Что проверяют
Понимаете ли вы, как устроен подсчёт ссылок изнутри. Вопрос глубокий, его задают на senior-уровне, и полный ответ здесь редкость.
Как отвечать
У объекта в Swift счётчик сильных ссылок хранится прямо в служебном слове заголовка, рядом с указателем на класс. Это быстро и не требует дополнительной памяти, пока хватает выделенных под счётчик битов и не нужны слабые ссылки.
Боковая таблица это отдельная структура, на которую объект начинает ссылаться, когда встроенного хранилища перестаёт хватать. Заводится она в двух случаях:
- появились слабые ссылки. Слабая ссылка обязана обнулиться в момент уничтожения объекта, а значит нужно место, где хранится её счётчик и признак «объект уничтожен». Слабые ссылки указывают не на объект, а на запись в боковой таблице, поэтому после уничтожения объекта они безопасно возвращают
nil; - счётчик переполнился, то есть ссылок стало слишком много для встроенного поля.
Зачем так сделано: платить памятью и лишним переходом за каждый объект нерационально, ведь у большинства объектов слабых ссылок нет вовсе. Боковая таблица создаётся лениво, только для тех объектов, которым она действительно нужна.
Практические следствия, которые стоит назвать: слабые ссылки дороже сильных и по памяти, и по времени доступа, потому что требуют обращения к таблице и блокировки при обновлении; unowned дешевле weak, поскольку не обнуляется и не требует такой записи, но при обращении к уничтоженному объекту роняет приложение.
Где спотыкаются
Считают, что счётчик ссылок всегда лежит в отдельной таблице.
Не могут объяснить, почему weak дороже unowned.
Ставят weak всюду «на всякий случай», добавляя накладные расходы там, где цикла ссылок и не было.