Ответ
По умолчанию экземпляры структур (value types) размещаются в стеке. Однако они могут быть перемещены в кучу (heap) в следующих случаях:
- Когда структура является свойством класса. Объект класса живет в куче, и все его свойства, включая структуры, размещаются там же.
- Когда структура захватывается escaping-замыканием. Замыкание, которое может пережить контекст, в котором оно создано, и его захваченные значения размещаются в куче.
- При использовании с existential типами (протоколами). Когда структура присваивается переменной типа протокола (например,
var item: SomeProtocol), она упаковывается в existential container, который может использовать кучу. - При работе с небезопасными указателями или внешними функциями, которые явно требуют выделения в куче.
Пример:
// 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
}
Почему это важно: Размещение в куче влечет накладные расходы на выделение/освобождение памяти и подсчет ссылок (для захваченных значений). Понимание этого помогает оптимизировать производительность, минимизируя неожиданные аллокации в куче.