Где в памяти хранится класс, который является свойством структуры в Swift?

Ответ

Ответ зависит от типа памяти самой структуры, но экземпляр класса всегда хранится в куче (heap).

Механика:

  • Структура (struct) — тип-значение. Если она локальная переменная, то хранится в стеке. Если свойство класса — в куче.
  • Класс (class) — ссылочный тип. Его экземпляр всегда создается в куче.
  • Свойство структуры, имеющее тип класса, содержит не сам объект, а ссылку на него. Эта ссылка хранится вместе со структурой, а объект — отдельно в куче.

Наглядный пример:

class MyClass { var value = 42 }
struct MyStruct { let object = MyClass() } // свойство - ссылка на класс

var structA = MyStruct() // Структура в стеке, MyClass в куче
var structB = structA    // Копируется ВСЯ структура (значение), но ссылка `object` в копии указывает на ТОТ ЖЕ объект в куче.

structB.object.value = 10
print(structA.object.value) // 10! Обе структуры разделяют один экземпляр класса.

Вывод: Объект класса живет в куче независимо от контекста. Структура хранит лишь ссылку на него.

Ответ 18+ 🔞

А, ну ты про это, про память в Свифте! Давай разжую, как есть, без соплей.

Смотри, тут всё просто, как три копейки, но есть один подвох, который всех новичков в пизду отправляет. Запоминай раз и навсегда.

Класс (class) — это как твой паспорт. Сам паспорт — это кусок пластика и бумаги, он лежит в одном конкретном месте (в столе, в сейфе). Это куча (heap). У тебя на руках только ксерокс с пометкой «где искать оригинал». Это ссылка. Куда бы ты эту бумажку ни понес — в бар, в ментовку, домой — все будут смотреть по этой пометке в один и тот же сейф. Изменят что-то в оригинале — всем, у кого ксерокс, станет известно. Экземпляр класса всегда, блядь, всегда живёт в куче.

Структура (struct) — это как наличные в кармане. Ты их потрогал — они твои. Передал другу — у тебя в кармане пусто, у него — есть. Это значение. Обычно оно болтается там, где удобно: в стеке вызовов, если это локальная переменная в функции. Но! Если ты эту структуру засунул внутрь класса — то она поедет туда же, куда и класс, то есть в кучу. Потому что она теперь часть того самого паспорта в сейфе.

А теперь главный пиздец, где все путаются:

Допустим, у тебя в структуре есть свойство, которое является... классом! Что хранится в структуре? Сам объект? Нихуя подобного!

Структура хранит ссылку на этот объект. Как та самая бумажка с адресом сейфа. Сама структура может быть в стеке, но объект, на который она ссылается, — он в куче, отдельно, как взрослый дядька.

Вот, смотри, реальный пример, чтобы мозг не взорвался:

class Пиздёныш { var сила = 9000 } // Класс. Живёт в куче.
struct Контейнер { let житель = Пиздёныш() } // Структура. В свойстве — ССЫЛКА на Пиздёныша в куче.

// Создаём структуру. Сама `boxA` — в стеке (условно). Но внутри неё ссылка.
var boxA = Контейнер()
// Копируем структуру. Всё значение копируется, включая ссылку!
var boxB = boxA

// Меняем объект через ссылку в КОПИИ структуры.
boxB.житель.сила = 1

// Смотрим, что стало с объектом в ИСХОДНОЙ структуре.
print(boxA.житель.сила) // Выведет 1, ёпта! Потому что обе ссылки ведут к одному и тому же Пиздёнышу в куче!

Видишь, в чём подвох? Скопировали мы структуру, да. Но скопировали мы значение ссылки, а не сам объект. Обе бумажки с адресом теперь указывают на один и тот же сейф. Полезли через одну бумажку, поменяли содержимое сейфа — все остальные владельцы таких же бумажек охуеют.

Итог, коротко и ясно: Объект класса — всегда в куче. Структура, если в ней есть свойство-класс, хранит не объект, а адресную бумажку на него. Копирование структуры копирует бумажку, а не то, что лежит по адресу. Вот и вся магия, ебать её в сраку.