Ответ
Память процесса в iOS делится на несколько сегментов, каждый со своим назначением и характеристиками.
| Область | Хранение | Управление | Скорость | Особенности |
|---|---|---|---|---|
| Стек (Stack) | Локальные переменные, аргументы функций, адреса возврата. | Автоматическое (LIFO). | Очень быстро. | Ограниченный размер (∼1 МБ на поток). Переполнение вызывает stack overflow. |
| Куча (Heap) | Динамически выделяемые объекты (экземпляры классов). | Вручную (MRR) или автоматически (ARC). | Медленнее стека. | Гибкий размер. Риск фрагментации и утечек (retain cycles). |
| Сегмент кода (Text/Code) | Исполняемые машинные инструкции программы. | Только для чтения. | — | |
| Глобальные/Статические данные | Глобальные и статические переменные (static, глобальные константы). |
Существуют всю жизнь приложения. | — | Инициализируются до main(). |
Практический пример:
func processUser() {
let localId = 123 // `localId` хранится в СТЕКЕ.
let user = User(name: "Alice") // Сам объект `User` в КУЧЕ.
// Ссылка `user` (указатель) — в СТЕКЕ.
}
// При выходе из функции `localId` и ссылка `user` автоматически удаляются из стека.
// Объект `User` в куче будет удален ARC, если на него нет других сильных ссылок.
Ключевое различие: Типы значений (Int, String, struct, enum) обычно хранятся в стеке (или внутри других объектов). Типы ссылок (class, closure) — их данные в куче, а ссылка на них — в стеке.