Практика обработки исключений Try-catch для iPhone / Objective-C - PullRequest
27 голосов
/ 09 сентября 2010

Извиняюсь, если на этот вопрос уже был дан ответ где-то еще, но я не смог найти никакого решающего ответа при поиске по нему:

Мне интересно, когда блоки try-catch должны использоваться в приложениях для объективов c iPhone. «Введение в язык программирования Objective-C» от ​​Apple гласит, что исключения являются ресурсоемкими и что «не следует использовать исключения для общего управления потоком данных или просто для обозначения ошибок». Прочитав здесь несколько связанных вопросов, я также понял, что люди редко используют этот метод на практике.

Таким образом, я предполагаю, что вопрос таков: в каких ситуациях целесообразно использовать блоки try-catch при разработке для iPhone / Objective-C и когда их абсолютно НЕ следует использовать?

Например, я мог бы использовать их, чтобы перехватывать границы и другие исключения при работе с объектами в массивах. У меня есть метод, который выполняет несколько задач с объектами, которые передаются в нескольких массивах. Метод возвращает nil, если произошла ошибка и блок try-catch может помочь мне перехватить исключения. Тем не менее, я мог бы, конечно, просто написать небольшие if-тесты здесь и там, чтобы гарантировать, что я, например, никогда не пытаюсь получить доступ к индексу за пределами массива. Что бы вы сделали в этой ситуации?

Большое спасибо!

Ответы [ 2 ]

28 голосов
/ 09 сентября 2010

Уместно использовать @ try / @ catch для устранения неисправимых ошибок. Никогда не уместно использовать @ throw / @ try / @ catch для выполнения операций, подобных потоку управления.

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

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

Ваш if-тест для проверки границ является гораздо более подходящим решением.

19 голосов
/ 09 сентября 2010

@ bbum ответ абсолютно правильный (и он знал бы ответ лучше, чем большинство). Чтобы уточнить немного ...

В Какао, как правило, следует избегать использования исключений (@try/@catch[/@finally]) для управления потоком. Как вы упоминаете, исключения несут необычайно большую стоимость (по сравнению с такими временами выполнения, как JVM или CLR, оптимизированные для использования исключений). Кроме того, большинство платформ Cocoa не являются безопасными для исключений. Таким образом, создание исключения в коде инфраструктуры Какао опасно и может привести к странным, трудным для диагностики и катастрофическим (возможно, потеря данных) ошибкам в вашем приложении.

Вместо использования исключений, код Какао использует NSError, чтобы сигнализировать об ошибках, которые восстанавливаются в приложении. Исключения используются для обозначения условий, после которых ваше приложение не может восстановиться. Таким образом, компонент UI, запрашивающий позицию «вне границ» в массиве модели, может сигнализироваться с ошибкой (представленной пользователю по причине, по которой его запрос не может быть выполнен) при попытке получить доступ к позиции «вне границ», учитывая Индекс, который, по вашему мнению, должен быть действительным, сигнализирует об исключительном состоянии, когда ваше приложение находится в несовместимом состоянии и, вероятно, должно умереть как можно скорее, прежде чем оно сможет нанести больше ущерба.

NSParameterAssert, например, сигналы с NSException, когда утверждение не выполняется.

Так когда следует использовать исключения или @try/@catch? Если вы используете библиотеку C / C ++, которая использует исключения, вы должны перехватить эти исключения, прежде чем они могут быть возвращены через код Какао. Точно так же, если вы серьезно относитесь к непротиворечивости состояния в вашем приложении, вы должны вызвать исключение, как только обнаружите, что ваше состояние несовместимо (и неисправимо).

...