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 не используются в качестве общего механизма обработки ошибок, как и другие.