В каких случаях структура (struct) в Swift хранится в куче (heap)?

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

Ответ

Структуры — это value-типы и по умолчанию хранятся в стеке. Однако они могут быть размещены в куче косвенно, если становятся частью reference-типа или когда этого требует семантика копирования при записи (Copy-on-Write, CoW).

Основные случаи:

  1. Когда структура является свойством класса: Классы (reference-типы) хранятся в куче, и все их свойства, включая структуры, размещаются там же.

    struct Point { var x, y: Int }
    class Box {
        var point: Point // Структура `Point` хранится в куче внутри экземпляра `Box`
    }
  2. Когда структура захватывается escaping-замыканием: Замыкание, которое может пережить контекст, в котором оно создано, хранится в куче и захватывает все используемые в нем значения.

    var storedClosure: (() -> Void)?
    func captureStruct() {
        let myStruct = MyStruct()
        storedClosure = { print(myStruct) } // `myStruct` захватывается и попадает в кучу
    }
  3. При работе с коллекциями, использующими CoW: Стандартные типы, такие как Array, Dictionary, String, хранят свои буферы в куче. При помещении в них структуры, она также окажется там.

    struct Item { var id: Int }
    var array = [Item(id: 1)] // Буфер массива и элемент `Item` находятся в куче.

Вывод: Сама по себе структура не «попадает» в кучу напрямую. Это происходит, когда она становится частью другого объекта, который управляется подсчетом ссылок (класс, escaping-замыкание, CoW-буфер).