在@try-@catch-@finally块中,是使用finally还是继续正常?

时间:2022-06-02 22:19:51

This is a simple Objective-C question.

这是一个简单的Objective-C问题。

When you use a @trythe work flow can run in 2 ways

当您使用@ try工作流时,工作流可以以两种方式运行。

  • If some NSException appear, the code immediately jump to @catch block and than to @finally
  • 如果出现一些NSException,则代码立即跳转到@catch块,而不是@finally
  • If not, finish to run the @try block and than run @finally
  • 如果没有,finish将运行@try块并运行@finally

So, what is the difference to use or not use the @finally block? If I use only:

那么,使用或不使用@finally块有什么区别呢?如果我只使用:

-(void)function{
    @try {
     ...
    }
    @catch (NSException *exception) {
     ...
    }
    >>>The workflow will run this line in any case?
}

Than the rest of the function will run, or only the @catch block if a NSException is created?

如果创建了一个NSException,那么其余的函数将会运行,或者只有@catch块?

3 个解决方案

#1


15  

"A @finally block contains code that must be executed whether an exception is thrown or not." Does code in finally get run after a return in Objective-C?

“@finally块包含必须执行的代码,无论是否抛出异常。”在Objective-C中返回后,代码最终会运行吗?

The finally block exists to release/clean up resources like open sockets, open files, database locks, semaphore locks, and so on.

最终块用于释放/清理资源,如打开套接字、打开文件、数据库锁、信号量锁等。

If an error occurs inside of the catch block or the catch block rethrows the exception, then the line:

如果捕获块内部发生错误或捕获块重新抛出异常,则行:

>>>The workflow will run this line in any case?

is not executed. However, the code in the finally block should be executed. The finally block is the last, best chance to exit cleanly from an application that is about to crash. Even if the application is not about to crash, it is still the best place to cleanup resources because the code inside the finally block is more likely to be executed under unexpected conditions than code outside of the finally block.

不执行。但是,应该执行finally块中的代码。最后一个是最后一个,最好的机会从即将崩溃的应用程序中退出。即使应用程序不会崩溃,它仍然是清理资源的最佳位置,因为finally块中的代码更可能在意外情况下执行,而不是在finally块之外的代码中执行。

#2


4  

A couple things to note:

有几点需要注意:

  1. The @catch block is not required, you can have @try-@finally, and use the @finally block for anything (e.g. cleanup) that must happen even if an exception occurs
  2. @catch块不是必需的,您可以使用@try-@finally,并将@finally块用于即使发生异常也必须发生的任何事情(例如清理)
  3. The @catch block doesn't have to catch NSException, it may (and probably should) be changed to catch more specific exceptions. In that case the @catch block, along with the code below the @try-@catch-@finally, would not be run depending on the exception
  4. @catch块不一定要捕获NSException,它可能(也可能应该)被更改以捕获更具体的异常。在这种情况下,@catch块和@try-@catch-@finally下面的代码不会根据异常运行

#3


3  

Few important points that were missed in other's answers here.

在其他的回答中,没有几个重要的要点遗漏了。

  • Apple does NOT recommend the use of @try @catch @finally clauses in production code. Their penalty is too high, and the real benefits are few. In C++ where defensive code is all over the place, you can design your application to be "exception based" meaning, all the code is designed for stack-rollback and throwing and rethrowing exceptions until they reach the top level of the stack. This is NOT the case in Obj-C, and even in C++ this paradigm kills most compiler optimizations, because the compiler cannot shortcut any scenario as an exception can break it in the middle.
  • 苹果不建议在产品代码中使用@try @catch @finally子句。他们的惩罚太高了,而真正的好处却很少。在c++中,防御性代码随处可见,您可以将应用程序设计为“基于异常”的含义,所有代码都是为堆栈回滚而设计的,并抛出异常,直到它们到达堆栈的顶层。这在object -C中不是这样的,即使在c++中,这种模式也会扼杀大多数编译器优化,因为编译器不能对任何场景进行快捷操作,因为异常会在中间中断。
  • However --- Apple provides the try/catch/finally mechanism in Obj-C, so you can create debug-configuration-only code, that will help you identify and catch (literally) your bugs BEFORE releasing the application to the public.
  • 然而-- Apple在object -c中提供了try/catch/finally机制,因此您可以创建只有调试配置的代码,这将帮助您在向公众发布应用程序之前识别和捕获错误。
  • In addition Apple provides a complete (and beautiful) "Error handling" paradigm and protocol, backed up in API (NSError object, nested NSErrors NSError recovery protocol, NSError display API etc.) that is suitable for runtime error handling in your application - in "release" builds of your applications.
  • 此外,苹果提供了一个完整的(和美丽的)“错误处理”范式和协议,在API (NSError对象、嵌套NSErrors NSError恢复协议、NSError显示API等)中备份,适用于应用程序中的运行时错误处理——在“发布”构建应用程序中。
  • The above is correct for both iOS and MacOS-X error handling.
  • 以上是对iOS和MacOS-X错误处理都是正确的。

So, the whole discussion about the use of @finally here are a little exaggerated.

所以,关于使用@finally的整个讨论有点夸张。

#1


15  

"A @finally block contains code that must be executed whether an exception is thrown or not." Does code in finally get run after a return in Objective-C?

“@finally块包含必须执行的代码,无论是否抛出异常。”在Objective-C中返回后,代码最终会运行吗?

The finally block exists to release/clean up resources like open sockets, open files, database locks, semaphore locks, and so on.

最终块用于释放/清理资源,如打开套接字、打开文件、数据库锁、信号量锁等。

If an error occurs inside of the catch block or the catch block rethrows the exception, then the line:

如果捕获块内部发生错误或捕获块重新抛出异常,则行:

>>>The workflow will run this line in any case?

is not executed. However, the code in the finally block should be executed. The finally block is the last, best chance to exit cleanly from an application that is about to crash. Even if the application is not about to crash, it is still the best place to cleanup resources because the code inside the finally block is more likely to be executed under unexpected conditions than code outside of the finally block.

不执行。但是,应该执行finally块中的代码。最后一个是最后一个,最好的机会从即将崩溃的应用程序中退出。即使应用程序不会崩溃,它仍然是清理资源的最佳位置,因为finally块中的代码更可能在意外情况下执行,而不是在finally块之外的代码中执行。

#2


4  

A couple things to note:

有几点需要注意:

  1. The @catch block is not required, you can have @try-@finally, and use the @finally block for anything (e.g. cleanup) that must happen even if an exception occurs
  2. @catch块不是必需的,您可以使用@try-@finally,并将@finally块用于即使发生异常也必须发生的任何事情(例如清理)
  3. The @catch block doesn't have to catch NSException, it may (and probably should) be changed to catch more specific exceptions. In that case the @catch block, along with the code below the @try-@catch-@finally, would not be run depending on the exception
  4. @catch块不一定要捕获NSException,它可能(也可能应该)被更改以捕获更具体的异常。在这种情况下,@catch块和@try-@catch-@finally下面的代码不会根据异常运行

#3


3  

Few important points that were missed in other's answers here.

在其他的回答中,没有几个重要的要点遗漏了。

  • Apple does NOT recommend the use of @try @catch @finally clauses in production code. Their penalty is too high, and the real benefits are few. In C++ where defensive code is all over the place, you can design your application to be "exception based" meaning, all the code is designed for stack-rollback and throwing and rethrowing exceptions until they reach the top level of the stack. This is NOT the case in Obj-C, and even in C++ this paradigm kills most compiler optimizations, because the compiler cannot shortcut any scenario as an exception can break it in the middle.
  • 苹果不建议在产品代码中使用@try @catch @finally子句。他们的惩罚太高了,而真正的好处却很少。在c++中,防御性代码随处可见,您可以将应用程序设计为“基于异常”的含义,所有代码都是为堆栈回滚而设计的,并抛出异常,直到它们到达堆栈的顶层。这在object -C中不是这样的,即使在c++中,这种模式也会扼杀大多数编译器优化,因为编译器不能对任何场景进行快捷操作,因为异常会在中间中断。
  • However --- Apple provides the try/catch/finally mechanism in Obj-C, so you can create debug-configuration-only code, that will help you identify and catch (literally) your bugs BEFORE releasing the application to the public.
  • 然而-- Apple在object -c中提供了try/catch/finally机制,因此您可以创建只有调试配置的代码,这将帮助您在向公众发布应用程序之前识别和捕获错误。
  • In addition Apple provides a complete (and beautiful) "Error handling" paradigm and protocol, backed up in API (NSError object, nested NSErrors NSError recovery protocol, NSError display API etc.) that is suitable for runtime error handling in your application - in "release" builds of your applications.
  • 此外,苹果提供了一个完整的(和美丽的)“错误处理”范式和协议,在API (NSError对象、嵌套NSErrors NSError恢复协议、NSError显示API等)中备份,适用于应用程序中的运行时错误处理——在“发布”构建应用程序中。
  • The above is correct for both iOS and MacOS-X error handling.
  • 以上是对iOS和MacOS-X错误处理都是正确的。

So, the whole discussion about the use of @finally here are a little exaggerated.

所以,关于使用@finally的整个讨论有点夸张。