Ответ
Место хранения переменной определяется её типом (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 проверил: «Ссылка-то одна была? Уничтожаем!» — и объект в куче пошёл нахуй.
Вот и вся магия, ёпта. Главное — понимать, с кем имеешь дело: с простым значением, которое само за себя, или с хитрым объектом, за которым надо следить. И тогда никаких сюрпризов с памятью не будет, а то ведь можно такого наворотить, что потом дебажить — волосы на жопе поседеют.