← Назад к вопросам

В чем разница между классами Error и Exception?

1.0 Junior🔥 142 комментариев
#Тестирование и отладка

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Error и Exception в Swift (и iOS)

В Swift (и Objective-C) термины Error и Exception относятся к двум разным механизмам обработки нештатных ситуаций, каждый из которых имеет свои особенности, назначение и область применения.


1. Error (Ошибки) — Swift-овый механизм для ожидаемых нештатных ситуаций

Error — это тип, используемый в современном Swift для представления ожидаемых, recoverable (восстанавливаемых) ошибок, которые могут возникнуть в ходе нормального выполнения программы (например, ошибки сети, ошибки парсинга JSON, ошибки валидации данных).

  • Протокол Error: В Swift нет конкретных классов Error или Exception. Вместо этого существует протокол Error (пустой протокол), который могут реализовывать любые типы (структуры, классы, перечисления) для описания ошибок. Чаще всего используют enum для группировки различных случаев ошибок.
  • Механизм обработки: Для работы с Error используется синтаксис throws / try / catch.

Пример использования Error:

enum NetworkError: Error {
    case noInternetConnection
    case serverError(code: Int)
    case invalidResponse
}

func fetchData(from url: URL) throws -> Data {
    // Проверка соединения
    if !isConnected {
        throw NetworkError.noInternetConnection
    }
    // ... выполнение запроса
    // Если статус код ответа 500
    throw NetworkError.serverError(code: 500)
}

// Обработка с помощью do-try-catch
do {
    let data = try fetchData(from: someURL)
    // Обработка успешного результата
} catch NetworkError.noInternetConnection {
    print("Проверьте подключение к интернету")
} catch NetworkError.serverError(let code) {
    print("Ошибка сервера с кодом: \(code)")
} catch {
    print("Неизвестная ошибка: \(error)")
}

Ключевые особенности Error:

  • Ожидаемые ситуации: Ошибки, которые программа должна предусматривать и корректно обрабатывать (показывать пользователю сообщение, делать повторный запрос).
  • Swift-овый механизм: Это основной, "родной" способ обработки ошибок в Swift.
  • Локальность: Ошибка выбрасывается и обрабатывается в пределах одного вызова функции.
  • Не влияет на поток выполнения: Программа продолжает работу после обработки ошибки в блоке catch.

2. Exception (Исключения) — Механизм Objective-C для критических ситуаций

Exception — это механизм, пришедший из Objective-C и Cocoa, предназначенный для неожиданных, критических (unrecoverable) ситуаций, которые обычно указывают на серьезную ошибку программиста или фатальную проблему в состоянии программы (например, выход за границы массива, попытка вызвать метод у nil объекта до появления Optional).

  • Классы NSException: В Objective-C/Foundation существуют конкретные классы исключений, такие как NSException.
  • Механизм обработки: Используются конструкции @try / @catch / @finally (в Objective-C) или, в крайне редких случаях, catch в Swift для исключений, возникающих в Cocoa-фреймворках.

Пример возникновения исключения (не для обработки!):

// В Swift такие ситуации обычно предотвращаются другими механизмами
let array = [1, 2, 3]
// Попытка доступа к несуществующему индексу ДОЛЖНА приводить к исключению,
// но в Swift это вызывает runtime error (краш), а не исключение для обработки.

// В Cocoa некоторые API могут выбросить исключение, например:
let invalidRegex = try NSRegularExpression(pattern: "[invalid", options: [])
// Некорректный regex вызовет исключение внутри Cocoa, которое Swift может преобразовать в Error.

Ключевые особенности Exception:

  • Критические ситуации: Используются для ошибок, которые часто указывают на баг в программе и которые обычно не предполагается обрабатывать для продолжения нормальной работы.
  • Межъязыковой мост: Это механизм из мира Objective-C/Cocoa. В Swift они используются редко и преимущественно "под капотом" фреймворков.
  • Не рекомендуется для обработки в Swift: В Swift не следует использовать try/catch для обработки исключений Cocoa. Вместо этого большинство API, которые могут выбрасывать исключения в Objective-C, в Swift переработаны для выбрасывания Error (например, многие методы NSRegularExpression, JSONSerialization).

3. Сравнение и рекомендации для iOS разработчика

КритерийError (Swift)Exception (Objective-C/Cocoa)
НазначениеОжидаемые, восстанавливаемые ошибки (бизнес-Logic, сеть, данные).Неожиданные, критические ошибки (программистские ошибки, фатальные состояния).
МеханизмПротокол Error, throws/try/catch.Класс NSException, @try/@catch/@finally.
Область примененияОсновной механизм для обработки ошибок в современном Swift.Внутренние механизмы Cocoa, не предназначен для явной обработки в Swift-коде.
Результат необработкиОшибка передается выше по стеку вызовов.Чаще всего приводит к крашу приложения.

Практические выводы:

  1. В Swift вы всегда используете Error для обработки любых ожидаемых неполадок в вашем коде или при работе с современными Swift-API.
  2. Вы никогда (почти) не пишете код, который явно обрабатывает Exception с помощью try-catch в Swift. Если вы вызываете Cocoa-метод, который может выбросить исключение (это указано в документации Apple как "throws an exception"), вы оборачиваете его вызов в блок do-catch, но Swift автоматически преобразует исключение в Error (типа NSError) для вас.
  3. Исключения чаще всего означают краш: Если в вашем Swift-приложении возникает неперехваченное исключение Cocoa (например, из-за некорректного использования API), это приведет к немедленному крашу приложения. Это сигнал о том, что вы используете API неправильно.
  4. Swift превращает многие исключения в ошибки: Фреймворки адаптируют свои Objective-C API для Swift, часто превращая исключения в throwing-функции, которые выбрасывают Error. Например, JSONSerialization.jsonObject(with:options:) в Objective-C мог выбросить исключение, а в Swift он объявлен как throws и возвращает Error.

Таким образом, для iOS разработчика, работающего в Swift, Error — это рабочий инструмент для ежедневной обработки сбоев, а Exception — это внутренний, исторический механизм Cocoa, который вы видите лишь косвенно, и ваша задача — избегать ситуаций, которые его вызывают.

В чем разница между классами Error и Exception? | PrepBro