Ответ
Да, такой блок должен быть помечен как @escaping.
По умолчанию в Swift параметры-функции являются non-escaping. Это означает, что они должны быть выполнены до завершения работы функции, в которую переданы. Если же блок сохраняется в свойство класса (или любой другой внешней переменной), его время жизни потенциально продлевается за рамки этой функции — он может быть вызван позже, асинхронно. Такой блок является escaping.
Пример, требующий @escaping:
class DataManager {
var completionHandler: (() -> Void)? // Блок хранится как свойство
func fetchData(completion: @escaping () -> Void) {
// Сохраняем блок для вызова позже
self.completionHandler = completion
// Имитируем асинхронную операцию
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
// Вызываем блок после завершения функции `fetchData`
completion()
}
}
}
Если убрать @escaping, компилятор выдаст ошибку: "Escaping closure captures non-escaping parameter 'completion'", так как блок «сбегает» за пределы области вызова функции.