【问题标题】:Does code in finally get run after a return in Objective-C?在 Objective-C 中返回后,代码最终会运行吗?
【发布时间】:2010-06-03 19:15:07
【问题描述】:

考虑以下代码:

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

如果something 无效并且我从try 中返回,@finally 中的代码是否执行?我认为应该是这样,但与我交谈过的其他人不这么认为,我目前无法对此进行测试。

【问题讨论】:

  • 结论是什么?它会执行吗?

标签: objective-c exception try-catch-finally


【解决方案1】:

@finally 代码始终根据herehere 执行。

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

【讨论】:

    【解决方案2】:

    是的。奇怪的是,确实如此。我不知道为什么,但我只是构建了一个测试并尝试了许多配置,并且每次都这样做。

    这里是配置:

    • 在 try 块中返回:停止执行 try 块并导致 finally 被执行
    • 在 try 块中返回并在 finally 中返回:停止执行 try 并在 finally 块和整个方法中停止执行。
    • 在 finally 块中返回:功能类似于在 try/catch/finally 块之外的正常返回。

    【讨论】:

    • 第一种情况并不奇怪。这就是finally 的意义所在。见stackoverflow.com/questions/65035/…
    • 你看,我希望return 超出try/catch/finally 块的范围并应用于该方法。我并不是说这样做是错误的,但它确实让我措手不及。这只是我从未关注过的事情。我想我一直把我的方法一直贯彻到最后;)
    【解决方案3】:

    使用 RAI 定义,Finally 块无论如何都会在该代码范围内针对特定资源执行。

    它与 Object 的~Destructor 有密切的关系。就像对象的~Destructor 总是执行一样,finally 块也会执行。

    【讨论】:

      【解决方案4】:

      是的。即使catch 块中有Exceptionfinally 也会被执行。

      如果您熟悉 C++,只需将finally 视为objectdestructor。无论对象中的语句处于何种状态,~Destructor 都会被执行。 但是您不能将return 放在finally 中[尽管有些编译器允许]。

      查看下面的代码:查看全局变量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
      

      【讨论】:

        【解决方案5】:

        是的,这里是一个示例 sn-p,输出是

        试试吧! 抓住! 终于!

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

        【讨论】:

          猜你喜欢
          • 2016-05-07
          • 2011-04-09
          • 1970-01-01
          • 2012-08-22
          • 1970-01-01
          • 1970-01-01
          • 2017-09-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多