Подтвердить что ты не робот

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

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

Мне интересно, когда в приложениях objective-c iPhone будут использоваться блоки try-catch. Apple "Введение в язык программирования objective-c" указывает, что исключения являются ресурсоемкими и что "не следует использовать исключения для общего управления потоком или просто для обозначения ошибок". Из чтения нескольких связанных вопросов здесь я также собираюсь, что люди не часто используют этот метод на практике.

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

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

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

4b9b3361

Ответ 1

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

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

Поведение любого исключения, созданного с помощью кода системы, - undefined.

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

Ответ 2

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

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

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

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

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