action по умолчанию non-escaping, но main.async сохраняет замыкание для выполнения после возврата execute. Параметр должен разрешать escaping-захват.
Что может вызвать ошибку компиляции
action по умолчанию non-escaping, но main.async сохраняет замыкание для выполнения после возврата execute. Параметр должен разрешать escaping-захват.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В этом фрагменте кода демонстрируется функция, принимающая замыкание и вызывающая его асинхронно в главной очереди.
func execute(action: () -> Void) {
DispatchQueue.main.async {
action()
}
}
Ответ
action по умолчанию non-escaping, но main.async сохраняет замыкание для выполнения после возврата execute. Параметр должен разрешать escaping-захват.
Базовое исправление — func execute(action: @escaping () -> Void). Если callback предназначен для UI и проект использует строгую конкурентность, контракт можно уточнить:
func execute(action: @escaping @MainActor @Sendable () -> Void) {
DispatchQueue.main.async { action() }
}
Это уже накладывает требования на захваты вызывающего кода. @escaping управляет временем жизни closure, @Sendable — безопасностью передачи через concurrency-границы, а MainActor — изоляцией исполнения. Одно не заменяет другое; выбирайте аннотации по реальному контракту callback.