В каких областях памяти хранятся переменные в Swift?

Ответ

Место хранения переменной определяется её типом (value type / reference type) и способом объявления.

Тип / Объявление Область памяти Управление памятью Особенности
Локальные переменные (value types)
let x = 5, var arr = [1,2]
Стек (Stack) Автоматическое (при выходе из scope) Быстрый доступ, размер известен на этапе компиляции.
Экземпляры классов (reference types)
let object = MyClass()
Куча (Heap) Автоматически (ARC) Сам объект в куче. Переменная object — это ссылка, хранящаяся в стеке.
Глобальные и статические переменные
let appName = "MyApp"
static let id = 123
Data Segment Время жизни программы Выделяется при запуске приложения.

Почему это важно?

  • Стек: Очень быстрый, но ограниченный по размеру. Идеален для временных данных.
  • Куча: Гибкий (динамическое выделение), но медленнее и требует управления через ARC (Automatic Reference Counting).
  • Data Segment: Для данных, которые должны существовать всё время работы приложения.

Пример, иллюстрирующий разницу:

struct Point { var x, y: Int } // Value type
class Label { var text: String } // Reference type

func test() {
    let point = Point(x: 0, y: 0) // `point` и его данные (0,0) — в стеке.
    let label = Label(text: "Hi") // Ссылка `label` — в стеке. Сам объект Label — в куче.
} // Здесь `point` уничтожается. Для `label` ARC уменьшает счетчик ссылок на объект в куче.

Ответ 18+ 🔞

О, смотри-ка, какой серьёзный вопрос подъехал! Ну что ж, давай разберём эту матёрую тему, где что лежит, как не перепутать и не наступить на грабли, которые потом по лбу ебут.

Вот, значит, у тебя есть переменные. И они, сука, не просто так в воздухе висят, а где-то хранятся. И место это зависит от того, кто они такие — простая «ценность» или хитрая «ссылка».

Кто ты такой / Как объявился Где живёт Кто убирает Особые приколы
Локальные переменные (value types)
let x = 5, var arr = [1,2]
Стек (Stack) Автоматически (как вышли из области видимости — чих-пых, и нету) Быстро, чётко, размер известен заранее. Как солдатская койка — занял, поспал, ушёл.
Экземпляры классов (reference types)
let object = MyClass()
Куча (Heap) ARC (этот умный мудак считает ссылки) Сам объект — в куче, в этой большой общей свалке. А переменная object у тебя в стеке — это просто бумажка с адресом этой свалки.
Глобальные и статические переменные
let appName = "MyApp"
static let id = 123
Data Segment (Сегмент данных) Живут, пока приложение не накрылось медным тазом Выделились при старте и сидят, как царь на троне, до самого конца.

А нахуя это знать?

  • Стек: Скорость — огонь, но места, блядь, мало. Как в телефонной будке — только для своих и ненадолго.
  • Куча: Места — овердохуища, можно развернуться. Но возня с выделением и уборкой (спасибо, ARC), плюс скорость помедленнее. Как общага — живут все, кто попал, но кто и когда выедет — хз.
  • Data Segment: Роскошь, блядь, вечность. Для того, что должно быть всегда под рукой, типа названия приложения или какого-нибудь уникального айдишника.

Ну и пример, чтобы совсем пиздец стало понятно:

struct Point { var x, y: Int } // Value type — простая парочка чисел
class Label { var text: String } // Reference type — хитрая сущность с текстом

func test() {
    let point = Point(x: 0, y: 0) // Всё семейство `point` — и переменная, и числа (0,0) — аккуратно сложились в стек.
    let label = Label(text: "Hi") // А вот тут трюк! Ссылка `label` — в стеке. А сам объект `Label` с его текстом "Hi" — отправился в большую жизнь, в кучу.
} // Тут функция кончилась. `point` мгновенно испарился из стека. А для `label` ARC проверил: «Ссылка-то одна была? Уничтожаем!» — и объект в куче пошёл нахуй.

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