Ответ
Добавьте ключевое слово @escaping перед типом замыкания в объявлении функции. Это указывает компилятору, что замыкание может быть сохранено и вызвано после возврата из функции.
Пример:
// Без @escaping (замыкание вызывается до выхода из функции)
func performSync(completion: () -> Void) {
completion() // Вызывается здесь
}
// С @escaping (замыкание может быть вызвано позже)
func performAsync(completion: @escaping (Result<Data, Error>) -> Void) {
DispatchQueue.global().async {
// Долгая операция
let result = fetchDataFromNetwork()
DispatchQueue.main.async {
completion(result) // Вызывается асинхронно, после возврата из performAsync
}
}
}
Важные последствия:
- При захвате
selfвнутри escaping-замыкания требуется явное указание (self.property) для предотвращения цикла сильных ссылок. Часто используют[weak self]. - Атрибут
@escapingобязателен для асинхронных колбэков, обработчиков таймеров, сетевых запросов и сохранения замыканий в свойства.