Что может вызвать ошибку компиляции

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.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее