Ответ 1
Ваше понимание правильное - NSError (или аналогичный) следует использовать для передачи информации об ошибках, а не исключений. Большинство Objective-C кода не являются безопасными для исключительных ситуаций и, по крайней мере, будут обладать ресурсами утечки. Как правило, никогда не позволяйте вашему коду утечка исключения в код другого пользователя - будь то Apple или третьи стороны. Некоторые сторонние структуры могут явно указывать, что они безопасны для исключения, но это редко.
По этому принципу вы можете понять, почему вы должны иметь обработчик исключений catch-all в вашем методе main
независимо. Но есть и другая причина: ваша операция будет выполняться по выделенному потоку. Исключения, выброшенные из вашей операции, будут распространяться по стеку, но не дальше. Логический вызывающий или владелец операции не получит их, поскольку они работают в другом потоке (или вообще не работают). Таким образом, утечка исключений либо убьет всю вашу программу, либо будет проглочена без каких-либо других указаний. Ваша программа может застрять в странном состоянии - так как вы не понимали, что произошла ошибка, вы можете продолжать ждать результата своей операции, которая никогда не появится.
Кроме того, у Apple есть раздел в Concurrency Руководство по программированию, где они говорят о Обработка ошибок и исключений. Их первая точка на "дискретных сущностях" ссылается на то, что я сказал в предыдущем абзаце:
Обработка ошибок и исключений
Поскольку операции по существу дискретных объектов внутри вашего приложения, они несут ответственность за обработки любых ошибок или исключений, которые возникают. В OS X v10.6 и более поздних версиях, метод запуска по умолчанию, предоставляемый классом NSOperation, не исключение catch. (В OS X v10.5 метод запуска делает catch и исключайте исключения.) Ваш собственный код всегда должен улавливать и подавлять исключений. Он также должен проверять коды ошибок и уведомлять соответствующие части вашего приложения по мере необходимости. И если вы замените метод начала, вы должны также поймать любые исключения в своем для предотвращения их отказа от основной поток.
Среди типов ситуаций с ошибками вы должны быть готовы к следующие:
- Проверить и обработать коды ошибок в стиле errno в стиле UNIX.
- Проверить явную ошибку коды, возвращаемые методами и функциями.
- Исключение исключений ваш собственный код или другие системные рамки.
- Ловить исключения самим классом NSOperation, который выдает исключения из следующие ситуации:
- Если операция не готова к выполнению, его метод запуска называется
- Когда операция выполняется или завершена (возможно, потому что он был отменен), и его метод запуска называется еще раз
- При попытке добавить блок завершения к операции, которая уже выполняется или завершено
- Когда вы пытаетесь получить результат объект NSInvocationOperation, который был отменен
Если ваш пользовательский код сталкивается с исключением или ошибкой, вы должны предпринять любые шаги необходимы для распространения этой ошибки на остальную часть вашего приложения. Класс NSOperation не предоставляет явные методы для передачи по кодам ошибок или исключениям в других частях вашего выражение. Поэтому, если такая информация важна для вашей приложения, вы должны предоставить необходимый код.