Objective-C: утверждение против исключения или ошибка

В Cocoa, когда следует использовать NSAssert, NSException, NSError?

Вот что я думал:

NSAssert. При создании любой клиентской программы, используемой для собственных программистов, для двойных правил проверки, соглашений, допущений или предварительных условий и пост-условий?

NSException. При создании сторонней библиотеки для других программистов, использующих библиотеку, чтобы они сразу узнали, когда вход недействителен?

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

Ответ 1

NSAssert генерирует исключение, если оно не выполняется. Таким образом, NSAssert - это короткий и простой способ записи и проверки любых допущений, которые вы сделали в своем коде. Это не (на мой взгляд) альтернатива исключениям, просто ярлык. Если утверждение терпит неудачу, в вашем коде что-то пошло не так, и программа не должна продолжаться.

Следует отметить, что NSAssert не будет скомпилирован в ваш код в сборке релизов, поэтому это обычно используется для проверки работоспособности во время разработки. Я на самом деле склонен использовать пользовательский макрос assert, который всегда активен.

В те времена, когда вы @throw использовали свой собственный NSException, когда вы определенно хотите его в сборке релизов, а также в таких вещах, как публичные библиотеки/интерфейс, когда некоторые аргументы недействительны или вы были вызваны неправильно, Обратите внимание, что это не стандартная практика для исключения @catch и продолжения работы приложения. Если вы попробуете это с некоторыми стандартными библиотеками Apple (например, Core Data), могут случиться плохие вещи. Подобно утверждению, если вызывается исключение, приложение должно заканчиваться довольно быстро, потому что это означает, что где-то есть ошибка программирования.

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

Ответ 2

Соглашение в Cocoa заключается в том, что исключение указывает на ошибку программиста. Многие из кода, включая код рамки, не предназначены для правильной работы после того, как выбрано исключение.

Любая ошибка, которая должна быть восстановлена, представлена ​​ NSError. Theres также система для представления NSError пользователю. Как вы говорите, это в основном полезно для ошибочных внешних ресурсов.

Концептуально утверждение является утверждением, что данный предикат всегда оценивает true; если это не так, программа нарушена. Хотя его поведение может быть изменено, семейство NSAssert по умолчанию является удобным способом метать NSInternalInconsistencyException (с возможностью их отключения в релиз-сборках).

Ответ 3

Изменить: В Xcode 4.2 утверждения по умолчанию отключены для релизов,

Теперь NSAssert не будет скомпилирован в ваш код в версии сборки, но вы можете изменить его в настройках сборки


@Майк Уэллер. В вашем ответе есть одна ошибка.

Следует отметить, что NSAssert не будет скомпилирован в ваш код в сборке релизов, поэтому это обычно используется для проверки работоспособности во время разработки.

Собственно, NSAssert будет скомпилирован в ваш код, если вы не добавите NS_BLOCK_ASSERTIONS в прекомпилированные файлы префикса.

В Технической ноте TN2190 мы можем найти:

Макросы, такие как NDEBUG, чтобы отключить C assert или NS_BLOCK_ASSERTIONS, чтобы отключить Foundation NSAssert, важно указать для ваших предварительно скомпилированных файлов префикса

Или вы можете прочитать это: Как узнать, отключен ли NSAssert в версиях сборки?

Ответ 4

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

Утверждения обычно используются при тестировании, и AFAIK не используются в качестве общего механизма обработки ошибок, как и другие.