Ответ
Место хранения зависит от типа замыкания:
- Для
non-escapingзамыканий: Захваченная структура (тип-значение) обычно остается в стеке. Замыкание выполняется синхронно в пределах жизни функции, и нет необходимости продлевать время жизни захваченных значений. - Для
@escapingзамыканий: Захваченная структура копируется и хранится в куче. Это необходимо, потому что замыкание может быть вызвано после завершения функции, и его контекст (включая захваченные значения) должен оставаться валидным.
Почему так происходит? Swift автоматически управляет памятью для контекста замыкания. Если замыкание может "сбежать" из текущей области видимости, компилятор выделяет память в куче для всего его контекста.
Пример:
struct SensorData { var value: Double }
var data = SensorData(value: 25.5)
// 1. Non-escaping замыкание (стек)
func processImmediately(using closure: (SensorData) -> Void) {
closure(data) // Вызывается здесь же
}
// 2. Escaping замыкание (куча)
var storedClosure: (() -> Void)?
func storeForLater(closure: @escaping () -> Void) {
storedClosure = closure // Замыкание сохраняется и может быть вызвано позже
}
storeForLater { [data] in // `data` копируется в кучу
print("Captured data: (data.value)")
}
Вывод: Структуры в @escaping замыканиях хранятся в куче, в non-escaping — обычно в стеке.