Ответ
Ключевое слово defer откладывает выполнение блока кода до момента выхода из текущей области видимости (функции, цикла, условия, do-блока). Это гарантирует выполнение cleanup-логики, даже если выход произошел из-за ошибки (throw) или досрочного return.
Основные правила:
- Порядок выполнения (LIFO): Код в блоках
deferвыполняется в обратном порядке — последний объявленныйdeferсрабатывает первым. - Гарантия выполнения: Блок
deferвыполнится при любом выходе из области видимости.
Типичные сценарии использования:
- Закрытие файловых дескрипторов или сетевых соединений.
- Освобождение ресурсов (например, снятие блокировки).
- Логирование завершения работы функции.
Пример:
func processFile(at path: String) throws -> String {
let fileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
defer {
// Этот код выполнится в самом конце функции,
// независимо от того, как она завершится.
fileHandle.closeFile()
print("Файл закрыт.")
}
let data = fileHandle.readDataToEndOfFile()
guard let content = String(data: data, encoding: .utf8) else {
throw FileError.invalidEncoding // defer сработает ПЕРЕД выбросом ошибки!
}
return content
}
Важно: defer не предназначен для управления потоком выполнения (как if/else). Его цель — обеспечить предсказуемую очистку ресурсов.