在Objective-C中,如果在return语句后面使用finally代码块,那么finally代码块会被执行吗?

15

考虑以下代码:

@try {
  if (something.notvalid)
  {
    return;
  }
  // do something else
} @catch (NSException *ex) {
  // handle exception
} @finally {
  NSLog(@"finally!");
}
如果在try块内部返回并且something无效,@finally中的代码是否会被执行? 我认为应该会执行,但我与其他人的观点不同,而且目前无法进行测试。

结论是什么?它会执行还是不会执行? - Shyam
5个回答

15

@finally代码块根据此处此处的说明,始终会被执行。

@finally代码块包含必须执行的代码,无论是否抛出异常。


4

是的。奇怪的是,确实如此。我不确定为什么,但我刚刚建立了一个测试并尝试了许多配置,每次都是这样。

以下是配置:

  • 在try块中返回:停止执行try块并导致finally被执行
  • 在try块和finally块中都返回:停止执行try块和finally块以及整个方法。
  • 在finally块中返回:像在try/catch/finally块外部正常返回一样运行。

2
第一个情况并不奇怪。这就是“finally”的重点。请参见https://dev59.com/tnVD5IYBdhLWcg3wKoSH。 - kennytm
你知道,我本来期望return语句会超越try/catch/finally代码块的作用域并应用于整个方法。我并不是说它这样做是错的,但它确实让我感到意外。这只是我从未关注过的事情。我想我总是将我的方法一直执行到最后的结果 ;) - lewiguez

2

根据 RAI 的定义,无论出现什么情况,finally 块都将在特定资源的代码范围内执行。

它与对象的 ~Destructor 有着类似的含义。与对象的 ~Destructor 总是被执行一样,finally 块也会被执行。


1
是的。即使在catch块中有异常,finally也会被执行。
如果您熟悉C ++,只需将finally视为对象的析构函数。无论对象内部语句的状态如何,析构函数都将被执行。 但是您不能在finally中放置return [尽管某些编译器允许]。
请参见下面的代码:查看全局变量y如何被更改。 还要看看Exception1如何被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();
        }
    }
}

输出:

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

因为问题涉及到ObjC并且标记为#objective-c,所以示例应该是ObjC而不是C#。 - undefined

0

是的,这里有一个示例片段,输出结果为

尝试! 捕获! 最终执行!

@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");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接