Вопрос проверяет понимание области жизни замыканий и необходимости пометить их как «убегающие» из текущей функции.
Если замыкание сохраняется вне тела функции (например, присваивается свойству или ставится в очередь), то оно «убегает» из области и выполняется позже — такое замыкание помечают @escaping. Это даёт понять компилятору, что нужно захватить переменные должным образом и управлять временем жизни замыкания.
Неотслеживаемое (non-escaping):
Замыкание выполняется внутри вызова функции и сразу уходит из стека после возвращения.
Убегающее (@escaping):
Замыкание сохраняется в свойстве, передаётся в асинхронный API или GCD.
Оно может выполняться позже, после выхода из функции.
Пример:
var completions: [() -> Void] = []
func doSomething(completion: @escaping () -> Void) {
completions.append(completion) // сохраняем
}
doSomething {
print("Done")
}
// Вызовем позже:
completions.forEach { $0() }Зачем требуется маркировка:
Компилятор вставляет захват self как strong или weak в зависимости от контекста.
Без @escaping нельзя сохранить замыкание, и компилятор выдаст ошибку.
Вывод:@escaping явно обозначает, что замыкание живёт дольше тела функции и будет вызвано позже, что важно для правильного управления памятью и захватов.