Ответ
Опциональное замыкание (() -> Void)? по умолчанию считается escaping. Явное указание @escaping не требуется, потому что сама опциональная природа (Optional) подразумевает, что замыкание может быть сохранено и вызвано позже, выходя за рамки текущего контекста функции.
Причина: Тип Optional — это перечисление (enum), которое может хранить значение (в данном случае замыкание) как ассоциированный параметр. Поскольку это значение может быть сохранено (например, в свойстве) и использовано асинхронно, компилятор Swift автоматически трактует его как escaping.
Пример:
func performAsyncAction(completion: (() -> Void)?) {
// Замыкание передаётся в асинхронный контекст -> оно escaping.
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
completion?() // Вызов может произойти после выхода из функции.
}
}
Контраст с non-escaping: Неопциональные параметры-замыкания по умолчанию non-escaping. Они гарантированно выполняются до выхода из функции, что позволяет компилятору проводить оптимизации.