Ответ
Side Table — это скрытая от разработчика вспомогательная структура памяти, которую ARC создает для объекта, когда на него появляется слабая (weak) или невладеющая (unowned) ссылка.
Что хранится в Side Table?
- Счетчик слабых ссылок (
weak). Отслеживает количествоweak-ссылок на объект. - Указатель на исходный объект. Нужен, чтобы
weak-ссылка могла проверить, "жив" ли еще объект. - Дополнительные флаги состояния объекта.
Как это работает?
class MyClass {}
// 1. Создается обычный объект. Side Table еще НЕТ.
var strongRef: MyClass? = MyClass() // Strong count = 1
// 2. Появляется weak-ссылка. ARC неявно создает Side Table.
weak var weakRef = strongRef // Strong count = 1, Weak count (в Side Table) = 1
// 3. Сильная ссылка обнуляется, объект уничтожается.
strongRef = nil // Strong count = 0 -> объект деаллоцируется.
// Side Table остается, Weak count = 1, но указатель на объект обнуляется.
// 4. При обращении через weak-ссылку получаем `nil`.
print(weakRef) // nil. Side Table сообщил, что объекта нет.
// Когда Weak count тоже станет 0, Side Table уничтожается.
Ключевая роль: Side Table позволяет weak-ссылкам безопасно становиться nil при деаллокации объекта, предотвращая краши, и является механизмом реализации unowned с проверкой на существование объекта.
Ответ 18+ 🔞
А, слушай, смотри, вот эта вся кухня с ARC, она же не так проста, как кажется, блядь! Ты думаешь, там просто счетчики плюсуют-минусуют? Хуй там плавал, ёпта!
Вот представь: создал ты объект, сильная ссылка на него. Всё, казалось бы, просто. Но как только появляется эта, блядь, слабая ссылка — weak — или, того хуже, unowned, тут-то и начинается магия, сука! ARC, этот хитрожопый менеджер памяти, тихой сапой создаёт на подхвате ещё одну структуру — Side Table, ёбана!
И что же эта манда с ушами, Side Table, в себе хранит? Да не абы что!
- Счётчик слабых ссылок (
weak). Это чтобы знать, сколько этих, блядь, слабаков на объект смотрит, не владея им по-настоящему. - Указатель на сам объект. Ну, чтобы
weak-ссылка могла потыкать его палочкой и проверить: «Ты живой ещё, пиздёныш? Или уже в лучший мир?». - Всякие там флажки состояния объекта, его внутренние тараканы.
А теперь смотри, как это в жизни работает, на примере, чтобы мозг не взорвался:
class MyClass {}
// 1. Всё начинается невинно. Создаётся объект. Side Table'а ещё нет, всё чисто.
var strongRef: MyClass? = MyClass() // Strong count = 1. Красота.
// 2. А тут появляется слабак! weak-ссылка. И тут ARC, блядь, как по волшебству, создаёт Side Table.
weak var weakRef = strongRef // Strong count всё ещё 1, а вот в Side Table Weak count становится = 1.
// 3. А теперь сильная ссылка говорит: «Да похуй!» и уходит в nil.
strongRef = nil // Strong count падает до 0 -> объект отправляется на тот свет, деаллоцируется.
// Но! Side Table-то остаётся, ёпта! Weak count в нём = 1, а указатель на объект обнуляется — труп, короче.
// 4. И вот когда какая-нибудь weak-ссылка попытается достучаться...
print(weakRef) // nil, блядь! Side Table ей честно сказал: «Объекта нет, иди нахуй».
// И только когда все слабаки отвалят (Weak count станет 0), Side Table сам накроется медным тазом.
И главный прикол в чём, понимаешь? Вся эта подпольная кухня с Side Table — она и есть тот самый волшебный пендель, который позволяет weak-ссылкам не виснуть в памяти, а культурно становиться nil. И unowned там тоже через эту же систему, с проверками, работает, чтобы не выстрелить тебе в ногу случайно. Вот так-то, не всё так просто, как кажется!