Где, кроме стека, может размещаться структура в Swift?

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

Ответ

По умолчанию экземпляры структур (value types) размещаются в стеке. Однако они могут быть перемещены в кучу (heap) в следующих случаях:

  1. Когда структура является свойством класса. Объект класса живет в куче, и все его свойства, включая структуры, размещаются там же.
  2. Когда структура захватывается escaping-замыканием. Замыкание, которое может пережить контекст, в котором оно создано, и его захваченные значения размещаются в куче.
  3. При использовании с existential типами (протоколами). Когда структура присваивается переменной типа протокола (например, var item: SomeProtocol), она упаковывается в existential container, который может использовать кучу.
  4. При работе с небезопасными указателями или внешними функциями, которые явно требуют выделения в куче.

Пример:

// 1. Структура как свойство класса → куча
class Container {
    var data: MyStruct // MyStruct размещается в куче вместе с объектом Container
}

// 2. Захват escaping-замыканием → куча
func createEscapingClosure() -> () -> Void {
    var capturedStruct = MyStruct(value: 10)
    return { // Замыкание может быть вызвано позже
        print(capturedStruct.value) // capturedStruct перемещена в кучу
    }
}

struct MyStruct {
    var value: Int
}

Почему это важно: Размещение в куче влечет накладные расходы на выделение/освобождение памяти и подсчет ссылок (для захваченных значений). Понимание этого помогает оптимизировать производительность, минимизируя неожиданные аллокации в куче.