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.
@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.
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");
精彩评论