gpt4 book ai didi

objective-c - 为什么 NSOperation 示例代码使用 @try & @catch

转载 作者:太空狗 更新时间:2023-10-30 03:26:17 25 4
gpt4 key购买 nike

在 Apple 的并发编程指南中,NSOperation 子类示例(非并发和并发变体)使用异常处理,我想知道为什么他们在操作中鼓励这种风格。

list 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 处理。 (我可能被误导的理解来自 thisthis 之类的东西)

我想知道 NSOperations 是否提出了异常处理很重要的特定情况,或者这是否是该指南的特定作者更喜欢的风格。

作为旁注,一些 NSOperation 示例代码遵循这种风格,其他示例则没有。大多数高知名度的 OSS 不使用异常(例如 AFNetworking)。

最佳答案

你的理解是正确的——NSError(或类似的)应该用来传达错误信息,而不是异常。大多数 Objective-C 代码都不是异常安全的,至少会泄漏资源。作为一般规则,永远不要让您的代码将异常泄漏到其他任何人的代码中——无论是 Apple 的还是第三方的。一些第 3 方框架可能明确表明它们是异常安全的,但这种情况很少见。

根据该原则,您可以明白为什么无论如何都应该在 main 方法中包含一个包罗万象的异常处理程序。但实际上还有另一个原因:您的操作将在专用线程上运行。从您的操作中抛出的异常将传播到堆栈中,但不会传播得更远。操作的逻辑调用者或所有者不会得到它们,因为它们在不同的线程上运行(或根本不运行)。所以泄漏的异常要么杀死你的整个程序,要么在没有其他迹象的情况下被静静地吞噬。然后您的程序可能会陷入一种奇怪的状态 - 由于您没有意识到发生了错误,您可能会继续等待永远不会到达的操作结果。

此外,Apple 在 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 NSOperation 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 NSInvocationOperation object that was canceled

If 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.

关于objective-c - 为什么 NSOperation 示例代码使用 @try & @catch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13671028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com