Question

Consider the following code:

@try {
  if (something.notvalid)
  {
    return;
  }
  // do something else
} @catch (NSException *ex) {
  // handle exception
} @finally {
  NSLog(@"finally!");
}

If something is not valid and I return from within the try, does the code in @finally execute or not? I believe that it should but others I've spoken to don't think so and I'm unable to test this at the moment.

Was it helpful?

Solution

@finally code always executes according to here and here.

A @finally block contains code that must be executed whether an exception is thrown or not.

OTHER TIPS

Yes. Oddly enough, it does. I'm not sure why, but I just built a test and tried a number of configurations and every time it did.

Here were the configs:

  • Return in try block: stopped execution of try block and caused finally to be executed
  • Return in try block and return in finally: stopped execution of try and stopped execution in finally block and the entire method.
  • Return in finally block: functioned like normal return outside of a try/catch/finally block.

With the RAI definition, Finally block will anyhow executed with that code scope, for particular resource.

It has a close meaning with Object's ~Destructor. As same as an object's ~Destructor always executes, finally block also executes.

Yes. Even if there was an Exception within catch block, finally will be executed.

If you are familiar with C++, just think finally as the destructor of an object. What ever the state of a statement within the object, ~Destructor will be executed. But you cant put return within finally[some compilers allow though].

See the code below: See how global variable y been changed. Also see how Exception1 been covered by Exception2.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace finallyTest
{
    class Program
    {
        static int y = 0;
        static int testFinally()
        {
            int x = 0;
            try
            {
                x = 1;
                throw new Exception("Exception1");
                x = 2;
                return x;
            }
            catch (Exception e)
            {
                x = -1;
                throw new Exception("Exception2", e);
            }
            finally
            {
                x = 3;
                y = 1;
            }
            return x;
        }

        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine(">>>>>" + testFinally());
            }
            catch (Exception e)
            { Console.WriteLine(">>>>>" + e.ToString()); }
            Console.WriteLine(">>>>>" + y);
            Console.ReadLine();
        }
    }
}

output:

    >>>>>System.Exception: Exception2 ---> System.Exception: Exception1
   at finallyTest.Program.testFinally() in \Projects\finallyTest\finallyTest\Program.cs:line 17
   --- End of inner exception stack trace ---
   at finallyTest.Program.testFinally() in \Projects\finallyTest\finallyTest\Program.cs:line 24
   at finallyTest.Program.Main(String[] args) in \Projects\finallyTest\finallyTest\Program.cs:line 38
>>>>>1

Yes, here is a sample snippet, the output is

try! catch! finally!

@try {
    NSLog(@"try!");

    NSException *e = [NSException
                      exceptionWithName:@"No Name"
                      reason:@"No Reason"
                      userInfo:nil];
    @throw e;


} @ catch (...)
{
    NSLog(@"catch!");
    return;
}
@finally
{
    NSLog(@"finally!");
}

NSLog (@"other code");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top