Могут ли value-типы (структуры, перечисления) в Swift храниться в куче?

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

Ответ

Да, могут. Хотя value-типы по умолчанию размещаются в стеке, существует несколько сценариев, при которых они попадают в кучу:

  1. Когда value-тип является свойством класса. Классы — reference-типы, их экземпляры всегда размещаются в куче, а значит, и все их свойства (включая структуры и перечисления) хранятся там же.
  2. Когда value-тип захвачен escaping-замыканием. Если замыкание, захватившее value-тип, само сохраняется в куче (например, передано в асинхронную задачу), то захваченные значения также будут размещены в куче.
  3. При использовании unsafe-операций (например, withUnsafeMutablePointer), которые могут явно работать с памятью в куче.

Пример:

class Container {
    var storedStruct: MyStruct // Хранится в куче, так как является свойством класса
}

struct MyStruct {
    var value: Int
}

let container = Container()
container.storedStruct = MyStruct(value: 42) // Экземпляр MyStruct теперь находится в куче

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