Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift vs Obj-C exceptions. What is stack unwinding? Why doesn't Swift do it?

There is a note in the Swift Docs that states the following:

Error handling in Swift resembles exception handling in other languages, with the use of the try, catch and throw keywords. Unlike exception handling in many languages—including Objective-C—error handling in Swift does not involve unwinding the call stack, a process that can be computationally expensive. As such, the performance characteristics of a throw statement are comparable to those of a return statement.

What does unwinding the call stack mean in Swift and Obj-c? Related question here but it is C++ specific. I know what the call stack is, but would like a more detailed explanation of unwinding.

If Swift doesn't unwind the call stack, what does it do instead?

Why can this be computationally expensive?

Summed up: I'd like to get a better understanding of how exceptions work and the execution flow in Swift.

like image 233
Brynjar Avatar asked Apr 05 '16 10:04

Brynjar


1 Answers

Unwinding the stack basically means that when an exception is thrown, the method is immediately interrupted, the caller of the method is immediately interrupted and so on until an exception handler (try-catch-finally) is found or until we reach the top of the stack, when the exception usually ends in interrupting the current thread.

That works pretty well in languages with a garbage collector but in general it can lead to memory leaks in languages with manual memory management. Also, since methods are interrupted in unexpected places, an exception often leads to undefined/unrecoverable program states.

That's why exception in all languages should be used sparingly and only to handle exceptional situations, not to handle normal program flow.

Obj-C exceptions weren't very good, with all the problems mentioned above (see NSException, @try-@catch-@finally), that's why nobody is using them. Instead, Obj-C came with error parameters (you pass a reference to a NSError variable and if the method fails, the error gets assigned into that variable). See Error Handling in Objective-C

Swift just came with another syntax for NSError. It's not a real exception handling (errors don't interrupt program execution). See Error Handling in Swift

Technically, every function/method that can throw an error in Swift only has an additional hidden parameter that is used to pass the error back to caller context.

If you want more information, just compare code in Swift 1.x and 2.x (1.x didn't have special grammar for error handling yet).

like image 55
Sulthan Avatar answered Sep 30 '22 19:09

Sulthan