Вложенные обработчики исключений

Обработчики исключений могут быть вложены так, чтобы исключение, повышенное во внутреннем домене, могло быть обработано локальным обработчиком исключений и любым числом затрагивания обработчиков исключений. Этот проект позволяет исключению быть обработанным кодом, который, несмотря на то, что это далее от кода, фактически генерирующего исключение ̦, мог бы иметь больше знания об условиях, приводящих к исключению.

Обработчики вложенной исключительной ситуации с директивами компилятора

Чтобы понять, как обработчики вложенной исключительной ситуации, определенные с помощью директив компилятора, вызываются, рассмотрите фрагмент кода в Перечислении 1.

  Бросок перечисления 1 и перебросок исключения

@try {
    // ...
    if (someError) {
        NSException *theException = [NSException exceptionWithName:MyAppException reason:@"Some error just occurred!" userInfo:nil];
        @throw theException;
    }
}
@catch (NSException *exception) {
    if ([[exception name] isEqualToString:MyAppException]) {
        NSRunAlertPanel(@"Error Panel", @"%@", @"OK", nil, nil,
                localException);
    }
    @throw; // rethrow the exception
}
@finally {
    [self cleanUp];
}

В этом коде исключение (exception) брошен снова в конце локального обработчика, позволив обработчику исключений затрагивания принять некоторые дополнительные меры. Рисунок 1 иллюстрирует поток программного управления между обработчиками вложенной исключительной ситуации, создаваемыми с @catch директива.

  Поток управления рисунка 1 с обработчиками вложенной исключительной ситуации — использование директив
Control flow with nested exception handlers—using directives

Исключение, повышенное в домене Method 3's, заставляет выполнение переходить к его локальному обработчику исключений. В типовом приложении этот обработчик исключений запрашивает объект исключения для определения природы исключения. Локальный обработчик может обработать типы исключительной ситуации, которые он распознает и затем может повторно бросить объект исключения для передачи уведомления об исключении к обработчику, вложенному выше его — т.е. обработчику в Методе 2. Однако, прежде чем следующий внешний обработчик исключений вызывается, код в @finally блок, связанный с локальным обработчиком исключений, выполняется. (Это имеет импликации для управления памятью, как обсуждено в Обработке исключений и управлении памятью.)

Повторно брошенное исключение появляется к следующему более высокому обработчику так же, как если бы начальное исключение было повышено в его собственном домене обработки исключений. Метод 2 обработчик исключений снова может обработать исключение и может повторно бросить исключение в Метод 1 обработчик исключений; Метод 1 обработчик не получает перевызванную исключительную ситуацию до Метода 2 @finally блок выполняет свою задачу. Наконец, Метод 1 обработчик повторно бросает исключение. Поскольку нет никакого домена обработки исключений выше Метода 1, исключение передает обработчику необработанных исключений (см. Неперехваченные исключения).