Обработка полученных ошибок

Когда Вы отправляете a presentError: или presentError:modalForWindow:delegate:didPresentSelector:contextInfo: обменивайтесь сообщениями к определенным приемлемым объектам, перемещения сообщения последовательность объектов в приложении вызвала цепочку ошибочного респондента (см. Цепочку Ошибочного респондента). Реализация по умолчанию для большинства объектов в этой цепочке должна отправить willPresentError: метод к self прежде, чем отправить presentError: обменивайтесь сообщениями к следующему объекту. willPresentError: сообщение приводит примеры пользовательских подклассов возможность смотреть на ошибочный объект, отказанный цепочка и возможно настроить его. Когда ошибочный объект достигает конца цепочки, глобальный объект приложения, NSApp, выводит на экран ошибочное предупреждение пользователям; но прежде чем NSApp выводит на экран ошибочное предупреждение, он вызывает метод application:willPresentError:, предоставление его делегату та же возможность.

Следующие разделы обсуждают стратегии реализации willPresentError: и application:willPresentError: методы.

Передача ошибок цепочка ошибочного респондента

Если у Вас есть подкласс NSDocument, NSDocumentController, NSWindowController, NSWindow, NSPanel, или любой класс представления, можно переопределить willPresentError: метод для настройки представления ошибок. Это могло бы быть чем-то, что Вы хотите, чтобы экземпляр Вашего подкласса сделал, если он знает больше о контексте определенной ошибки, чем другие объекты в приложении. Обычно реализация willPresentError: исследует переданный - в NSError возразите и если, например, его локализованное описание недостаточно, или если подкласс знает, как восстановиться с ошибки, он создает новое NSError объект и возвраты это. В большинстве случаев специализированный ошибочный объект утаивает некоторую информацию от переданного - в объекте.

Реализация willPresentError: метод должен всегда использовать ошибочный домен и код ошибки как основание для решения, возвратить ли специализированный ошибочный объект. Не базируйтесь решение о строках в пользовательском информационном словаре для них может быть локализовано и может варьироваться между вызовами. Если Ваша реализация решает не настроить ошибку, не возвращайте переданный - в объекте непосредственно; вместо этого, отправьте willPresentError: сообщение к super. Перечисление 4-1 иллюстрирует некоторые из этих стратегий.

Перечисление 4-1  , Обрабатывающее ошибку, отказалось от цепочки ошибочного респондента

- (NSError *)willPresentError:(NSError *)error {
 
    if ([[error domain] isEqualToString:NSCocoaErrorDomain]) {
        switch([error code]) {
            case NSFileLockingError:
            case NSFileReadNoSuchFileError:
            { // Private method of custom subclass.
                return [self customizeError:error];
            }
            default:
                return [super willPresentError:error];
        }
    }
    return [super willPresentError:error];
}

Вы не должны делать подкласс для настройки NSError объект для представления. Вместо этого Ваш делегат приложения может реализовать application:willPresentError: метод. Те же наблюдения и инструкции, данные для willPresentError: выше применяются к реализации application:willPresentError:, за исключением того, что можно возвратить исходный ошибочный объект непосредственно, если Вы решаете не настроить его.

Настройка ошибочного объекта

В willPresentError: пример в Перечислении 4-1, закрытый метод вызывается для настройки ошибочного объекта. Это сделано для разъяснения структуры реализации. Но если бы код настройки был встроен, то он мог бы быть немного похожим willPresentError: реализация в Перечислении 4-2. Этот код проверяет, имеет ли переданный - в объекте причину отказа и, если это делает, это создает более специализированное описание ошибки, добавляя причину отказа. Тогда это создает новое NSError объект с этим различным описанием.

Перечисление 4-2  Настраивая объект NSError

- (NSError *)willPresentError:(NSError *)error {
 
    if ([[error domain] isEqualToString:NSCocoaErrorDomain]) {
        switch([error code]) {
            case NSFileLockingError:
            case NSFileReadNoSuchFileError:
            {
                NSString *locFailure = [error localizedFailureReason];
                if (locFailure) {
                    NSMutableDictionary *newUserInfo = [NSMutableDictionary
                        dictionaryWithCapacity:[[[error userInfo] allKeys] count]];
                    [newUserInfo setDictionary:[error userInfo]];
                    NSString *errorDesc = [NSString stringWithFormat:
                        NSLocalizedString(@”MyGreatApp cannot open the file. %@”, @””),
                        locFailure];
                    [newUserInfo setObject:errorDesc
                        forKey:NSLocalizedDescriptionKey];
                    NSError *newError = [NSError errorWithDomain:[error domain]
                        code:[error code] userInfo:newUserInfo];
                    return newError;
                }
                else {
                    return [super willPresentError:error];
                }
            }
            default:
                return [super willPresentError:error];
        }
    }
    return [super willPresentError:error];
}

В этом примере исходный ошибочный объект по существу клонирован для создания нового. Новый ошибочный объект содержит более определенное описание ошибки и добавляет причину отказа для нее.

Как отмечено мимоходом Ошибки Цепочка Ошибочного респондента, нет никакого различия в реализации willPresentError: и метод делегата application:willPresentError:, за исключением того, что в последнем методе можно возвратить по ошибке переданный объект непосредственно, если Вы не настраиваете его.