Может ли reference type (экземпляр класса) в Swift храниться на стеке?

«Может ли reference type (экземпляр класса) в Swift храниться на стеке?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сам объект (instance) reference type всегда размещается в куче (heap). Однако ссылка (указатель) на этот объект может временно находиться на стеке (stack).

Ключевые моменты:

  1. Хранение объекта: Память для экземпляра класса выделяется в куче. Это позволяет нескольким переменным владеть ссылкой на один объект (reference semantics) и обеспечивает динамическое время жизни.
  2. Хранение ссылки: Локальные переменные и параметры функции, которые хранят ссылку на объект, размещаются на стеке.

    class MyClass { var value = 10 }
    
    func processObject() {
        let localReference = MyClass() // `localReference` — ссылка в стеке, объект — в куче.
        // ...
    } // Стек фрейм очищается, счетчик ссылок на объект уменьшается.
  3. Исключения и оптимизации: Компилятор Swift (в частности, режим оптимизации -O) может применять escape analysis и, если объект не "сбегает" из локальной области видимости, разместить его на стеке или даже полностью удалить выделение (stack promotion). Это оптимизация, а не гарантированное поведение.
    func createTemporary() -> Int {
        let tempObject = MyClass() // Компилятор МОЖЕТ (но не обязан) разместить этот объект на стеке.
        tempObject.value = 42
        return tempObject.value
    }

Вывод: С точки зрения модели памяти Swift, программист должен считать, что экземпляры классов живут в куче. Компилятор может проводить оптимизации, но это не меняет семантику ссылочного типа.