Ошибочные объекты, домены и коды

Использование программ какао NSError объекты передать информацию об ошибках периода выполнения, о которых нужно сообщить пользователям. В большинстве случаев программа выводит на экран эту информацию об ошибке в диалоговом окне или листе. Но это может также интерпретировать информацию и или попросить, чтобы пользователь попытался восстановиться с ошибки или попытаться исправить ошибку самостоятельно.

Базовые атрибуты NSError объект — или, просто, ошибочный объект — являются ошибочным доменом, проблемно-ориентированным кодом ошибки и “пользовательским информационным словарем”, содержащим объекты, связанные с ошибкой, старше значащий строки восстановления и описание. Эта глава объясняет причину ошибочных объектов, описывает их атрибуты и обсуждает, как Вы используете их в коде Какао.

Почему имеют ошибочные объекты?

Поскольку они - объекты, экземпляры NSError класс имеет несколько преимуществ перед простыми кодами ошибки и строками ошибки. Они инкапсулируют несколько частей информации об ошибке сразу, включая локализованные строки ошибки различных видов. NSError объекты могут также быть заархивированы и скопированы, и они могут быть розданы в приложении и изменены. И несмотря на то, что NSError не абстрактный класс (и таким образом может использоваться непосредственно), можно расшириться NSError класс посредством разделения на подклассы.

Из-за понятия многоуровневых ошибочных доменов, NSError объекты могут встроить ошибки от базовых подсистем и таким образом предоставить более подробную и детальную информацию об ошибке. Ошибочные объекты также обеспечивают механизм для восстановления после ошибки путем содержания ссылки на объект, определяемый как восстановление attempter для ошибки.

Ошибочные домены

По в основном историческим причинам ошибочные коды в OS X являются отдельными в домены. Например, коды ошибки Углерода, вводящиеся как OSStatus, возникните в версиях OS X предшествования операционной системы Macintosh. С другой стороны, коды ошибки POSIX происходят из различных приспосабливающих POSIX «разновидностей» UNIX, таких как BSD. Платформа Основы объявляет в NSError.h следующие строковые константы для четырех главных ошибочных доменов:

Вышеупомянутая последовательность доменных констант указывает общее разделение на уровни доменов с ошибочным доменом Маха в нижнем слое. Вы получаете домен ошибки путем отправки NSError объект a domain сообщение.

В дополнение к четырем главным доменам существуют ошибочные домены, которые являются определенными для платформ или даже группам классов или отдельных классов. Например, веб-платформа Набора имеет свой собственный домен для ошибок в ее реализации Objective C, WebKitErrorDomain. В платформе Основы классы URL имеют свой собственный ошибочный домен (NSURLErrorDomain) также, как и классы XML (NSXMLParserErrorDomain). Сам класс NSStream определяет два ошибочных домена, один для ошибок SSL и другого для ошибок SOCKS.

Ошибочный домен Какао (NSCocoaErrorDomain) включает все коды ошибки для платформ Какао — кроме, конечно, для кодов ошибки в специфичных для класса доменах тех платформ. Эти платформы включают не только Основу, UIKit, и Набор Приложения, но и Базовые Данные и потенциально другие платформы Objective C. (Ошибочные домены в платформах Какао, которые являются отдельными от ошибочного домена Какао, были определены, прежде чем последний был представлен.)

Домены служат нескольким полезным целям. Они дают программам Какао способ идентифицировать подсистему OS X, обнаруживающую ошибку. Они также помогают предотвратить коллизии между кодами ошибки от различных подсистем с тем же числовым значением. Кроме того, домены допускают причинную связь между кодами ошибки на основе разделения на уровни подсистем; например, ошибка в NSOSStatusErrorDomain может иметь базовую ошибку в NSMachErrorDomain.

Можно создать собственные ошибочные домены и коды ошибки для использования в собственных платформах, или даже в собственных приложениях. Рекомендуется, чтобы строковая константа для домена имела форму com.компания.framework_or_app.ErrorDomain.

Коды ошибки

Код ошибки идентифицирует определенную ошибку в определенном домене. Это - целое число со знаком, присвоенное как значение символа программы. Вы получаете код ошибки путем отправки NSError объект a code сообщение. Как перечислено в Таблице 1-1, коды ошибки объявляются и документируются в один или несколько заголовочных файлов для каждого главного домена.

Табличные 1-1  Заголовочные файлы для кодов ошибки в главных доменах

Домен

Заголовочный файл

Мах

/usr/include/mach/kern_return.h

POSIX

/usr/include/sys/errno.h

Углерод (OSStatus)

/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MacErrors.h

Какао

Посмотрите таблицу 1-2.

Таблица 1-2 перечисляет платформы и заголовочные файлы, где в настоящее время объявляются коды ошибки в домене Cocoa.

Табличные 1-2  Заголовочные файлы, объявляющие коды ошибки

Платформа/Заголовок

Описание

<Foundation/FoundationErrors.h>

Универсальные коды ошибки Основы

<AppKit/AppKitErrors.h>

Коды ошибки Набора Универсального приложения

<CoreData/CoreDataErrors.h>

Базовые коды ошибки Данных

Для давания общее представление о том, как Вы могли бы протестировать на и реагировать на ошибки скажем, Вы хотите протестировать на лежание в основе ошибок POSIX во время работы, пишущей в файл. (Базовые ошибки объяснены по Базовой Ошибке.), Если Вы консультировались с кодами ошибки POSIX, объявленными в /usr/include/sys/errno.h, Вы видели бы список, подобный Перечислению 1-1.

  Часть перечисления 1-1 объявлений кода ошибки POSIX (errno.h)

#define EPERM       1       /* Operation not permitted */
#define ENOENT      2       /* No such file or directory */
#define ESRCH       3       /* No such process */
#define EINTR       4       /* Interrupted system call */
#define EIO         5       /* Input/output error */
#define ENXIO       6       /* Device not configured */
#define E2BIG       7       /* Argument list too long */
#define ENOEXEC     8       /* Exec format error */
#define EBADF       9       /* Bad file descriptor */
#define ECHILD      10      /* No child processes */
#define EDEADLK     11      /* Resource deadlock avoided */
                            /* 11 was EAGAIN */
#define ENOMEM      12      /* Cannot allocate memory */
#define EACCES      13      /* Permission denied */
#define EFAULT      14      /* Bad address *#H

Вы могли выбрать состояния ошибки, на которые Вы хотите протестировать и использовать их в коде, подобном этому в Перечислении 1-2.

  Тестирование перечисления 1-2 на определенные коды ошибки в определенном домене

// underError is underlying-error object of a Cocoa-domain error
if ( [[underError domain] isEqualToString:NSPOSIXErrorDomain] ) {
        switch([underError code]) {
            case EIO:
            {
                // handle POSIX I/O error
            }
            case EACCES:
            {
                // handle POSIX permissions error
            {
        // etc.
        }
}

Можно объявить владение кодами ошибки для использования собственными приложениями или платформами но коды ошибки должны принадлежать собственному домену. Вы никогда не должны добавлять коды ошибки к существующему домену, которым Вы не «владеете».

Пользовательский информационный словарь

Каждый NSError объект имеет “пользовательский информационный словарьдля содержания информации об ошибке вне домена и кода. Вы получаете доступ к этому словарю путем отправки a userInfo обменивайтесь сообщениями к NSError объект. Преимущество NSDictionary объект по другому виду контейнерного объекта состоит в том, что это гибко; это может даже перенести пользовательскую информацию об ошибке. Но все пользовательские информационные словари содержат (или может содержать), несколько предопределенных строк, и возразите значениям, связанным с ошибкой.

Локализованная информация об ошибке

Важная роль для NSError объекты состоят в том, чтобы содержать информацию об ошибке, которую программы могут вывести на экран в предупредительном диалоговом окне или листе. Эта информация обычно хранится в пользовательском информационном словаре как строки в нескольких категориях: описание, причина отказа, предложение восстановления и опции восстановления. (См. рисунок 1-1 для размещения этих строк на предупреждении.), Когда Вы создаете NSError объект, необходимо вставить локализованные строки в словарь, если Вы не хотите вычислить их лениво.

Можно обычно получать доступ к локализованной информации, связанной с NSError объект одним из двух способов. Можно отправить objectForKey: к пользовательскому информационному словарю, указывая надлежащий ключ. Или можно отправить эквивалентное сообщение в NSError объект. Однако необходимо отправить сообщение, а не использовать ключ словаря для доступа к локализованной строке. Ошибочный объект не мог бы сохранить строку в словаре, вместо этого приняв решение составить его динамично. Словарь разработан, чтобы быть механизмом нейтрализации, не единственным репозиторием строк ошибки. Используйте ключи словаря вместо этого для хранения собственных строк в пользовательском информационном словаре.

Следующие сводки включают и ключ словаря и метод, используемый для доступа к локализованной строке:

Описание ошибки

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

Пользовательский информационный ключ: NSLocalizedDescriptionKey

Метод: localizedDescription (никогда возвраты nil)

Причина отказа

Краткое предложение, объясняющее причину, почему произошла ошибка. Это обычно - часть описания ошибки. Методы такой как presentError: автоматически не выводите на экран причину отказа, потому что она уже включена в описание ошибки. Причина отказа для клиентов, только хотящих вывести на экран причину отказа.

Пользовательский информационный ключ: NSLocalizedFailureReasonErrorKey

Метод: localizedFailureReason (может возвратиться nil)

Примечание: Пример может помочь разъяснить отношение между причиной отказа и описанием ошибки. Ошибочный объект имеет описание ошибки “Файла, не мог быть сохранен, потому что диск полон”. Сопроводительной причиной отказа является “Диск, полно”.

Предложение восстановления

Вторичное предложение, идеально говорящее пользователям, что они могут сделать для восстановления с ошибки. Это появляется ниже описания ошибки в более легкой гарнитуре. Если предложение восстановления относится к кнопкам ошибочного предупреждения, оно должно использовать те же заголовки, как указано для опций восстановления (NSLocalizedRecoveryOptionsErrorKey). Можно использовать эту строку в качестве чисто информативного сообщения, дополняя причина отказа и описание ошибки.

Пользовательский информационный ключ: NSLocalizedRecoverySuggestionErrorKey

Метод: localizedRecoverySuggestion (может возвратиться nil)

Опции восстановления

Массив заголовков (как строки) для кнопок ошибочного предупреждения. По умолчанию предупредительные листы и диалоговые окна для сообщений об ошибках имеют только кнопку «OK» для отклонения предупреждения. Первая строка в массиве является заголовком самой правой кнопки, следующая строка является заголовком кнопки только налево от первого и т.д. Обратите внимание на то, что, если восстановление attempter указано для ошибочного объекта, массив options восстановления должен содержать больше чем одну строку. Восстановление attempter получает доступ к опциям восстановления для интерпретации пользовательского выбора.

Пользовательский информационный ключ: NSLocalizedRecoveryOptionsErrorKey

Метод: localizedRecoveryOptions (если возвраты nil, подразумевает единственную “кнопку OK),

Рисунок 1-1  локализованные строки объекта NSError
The localized strings of an NSError object

Для интернационализации строк ошибки создайте a .strings файл для каждой локализации и места файл в соответственно именованном .lproj подкаталог Вашего пакета Resources каталог. Тогда используйте один из NSLocalizedString макросы для добавления локализованных строк к пользовательскому информационному словарю NSError объект. Для больше на интернационализации и строковой локализации, посмотрите Руководство по Интернационализации и Локализации.

Восстановление Attempter

NSError пользовательский информационный словарь объекта может также содержать восстановление attempter. Восстановление attempter является объектом, реализующим один или несколько методов NSErrorRecoveryAttempting неофициальный протокол. Во многих случаях это - тот же объект, создающий NSError объект, но это может быть любой другой объект, который может знать, как восстановиться с определенной ошибки.

Если восстановление attempter было указано для NSError объект и многократные опции восстановления были также указаны, когда ошибочное предупреждение выведено на экран, и пользователь выбирает опцию восстановления, восстановлению attempter дают шанс восстановиться с ошибки. Вы получаете доступ к восстановлению attempter путем отправки recoveryAttempter к NSError объект. Можно добавить восстановление attempter к пользовательскому информационному словарю с помощью ключа NSRecoveryAttempterErrorKey.

Для больше на объекте восстановления-attempter и его роли в обработке ошибок, посмотрите Ошибочных Респондентов и Восстановление после ошибки.

Лежание в основе ошибки

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

Вы получаете доступ к базовому ошибочному объекту при помощи NSUnderlyingErrorKey ключ словаря.

Проблемно-ориентированные ключи

Многие различные ошибочные домены указывают ключи для доступа к определенным единицам информации из пользовательского информационного словаря. Эта информация дополняет другую информацию в ошибочном объекте. Например, домен Cocoa определяет ключи NSStringEncodingErrorKey, NSURLErrorKey, и NSFilePathErrorKey.

Проверьте заголовочные файлы или документацию ошибочных доменов для обнаружения, какие проблемно-ориентированные ключи они объявляют.