清单2-4响应取消请求
- (void)main { @try { BOOL isDone = NO; while (![self isCancelled] && !isDone) { // Do some work and set isDone to YES when finished } } @catch(...) { // Do not rethrow exceptions. } }
我的理解是,通常异常处理在Objective-C代码中不是常见的做法 – 异常本质上是程序员错误,应该导致应用程序崩溃,而意外的输入最好由NSError处理. (我的错误认识来自this和this)
我想知道NSOperations是否提供了特殊情况,其中异常处理很重要,或者这更多是该指南的特定作者的首选风格.
作为旁注,一些NSOperation示例代码遵循这种风格,其他示例不.大多数高可见性OSS不使用例外(例如AFNetworking).
解决方法
通过这个原则,你可以看到为什么你应该在你的main方法中有一个catch-all异常处理程序.但实际上还有一个原因:您的操作将在专用线程上运行.从您的操作抛出的异常将传播到堆栈,但没有进一步.逻辑调用者或操作的所有者将不会得到它们,因为它们在不同的线程上运行(或根本不是).所以泄露的例外将会杀死你的整个程序,或者无需其他指示就可以静静地吞下去.您的程序可能会被困在一个奇怪的状态 – 由于您没有意识到发生错误,您可能会继续等待您的操作结果永远不会到达.
此外,苹果在Concurrency Programming Guide年有一个部分,他们谈论了Handling Errors and Exceptions.他们对“离散实体”的第一点指出了我在前一段所说的话:
Handling Errors and Exceptions
Because operations are essentially
discrete entities inside your application,they are responsible for
handling any errors or exceptions that arise. In OS X v10.6 and later,
the default start method provided by the 07002 class does not
catch exceptions. (In OS X v10.5,the start method does catch and
suppress exceptions.) Your own code should always catch and suppress
exceptions directly. It should also check error codes and notify the
appropriate parts of your application as needed. And if you replace
the start method,you must similarly catch any exceptions in your
custom implementation to prevent them from leaving the scope of the
underlying thread.Among the types of error situations you should be prepared to handle
are the following:
- Check and handle UNIX errno-style error codes.
- Check explicit error
codes returned by methods and functions.- Catch exceptions thrown by
your own code or by other system frameworks.- Catch exceptions thrown
by the NSOperation class itself,which throws exceptions in the
following situations:
- When the operation is not ready to execute but
its start method is called- When the operation is executing or finished
(possibly because it was canceled) and its start method is called
again- When you try to add a completion block to an operation that is
already executing or finished- When you try to retrieve the result of
an 07003 object that was canceledIf your custom code does encounter an exception or error,you should take whatever steps are needed to propagate that error to the rest of your application. The NSOperation class does not provide explicit methods for passing along error result codes or exceptions to other parts of your application. Therefore,if such information is important to your application,you must provide the necessary code.