Ответ
Нет, не всегда. Хотя структуры являются типами-значениями (value types) и по умолчанию размещаются в стеке, есть важные исключения, которые приводят к выделению памяти в куче (heap).
Когда структура находится в стеке?
- Локальные переменные внутри функции или метода.
- Параметры функций, передаваемые по значению (не
inout).
func example() {
var point = CGPoint(x: 10, y: 20) // Выделяется в стеке кадра функции `example`.
}
Когда структура может оказаться в куче?
-
Структура захватывается замыканием, которое escaping: Замыкание может пережить контекст, поэтому захваченные значения перемещаются в кучу.
struct Config { var timeout: Int } var storedClosure: (() -> Void)? func storeClosure() { let config = Config(timeout: 5) // Изначально в стеке. storedClosure = { print(config.timeout) } // `config` теперь в куче! } - Структура является свойством ссылочного типа (класса): Память для всего экземпляра класса выделяется в куче.
class Container { var config = Config(timeout: 5) // `config` лежит внутри памяти `Container` в куче. } - Структура содержит ссылочные типы: Сама структура-значение может находиться где угодно (стек/куча), но её свойство-класс всегда ссылается на объект в куче.
struct Wrapper { let object = NSObject() // Экземпляр NSObject — в куче. } - Использование
withUnsafeMutableBytesи т.п.: Работа с сырыми указателями не меняет расположение, но это низкоуровневая операция.
Ключевой вывод
Расположение структуры определяется контекстом её использования, а не только её определением. Компилятор Swift может оптимизировать размещение (например, используя COW — Copy-on-Write для больших структур), но семантика типа-значения сохраняется.