Получает ли код, наконец, запуск после возврата в Objective-C?

Рассмотрим следующий код:

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

Если something недействителен и я возвращаюсь из try, выполняет ли код в @finally или нет? Я считаю, что он должен, но другие, с которыми я говорил, не так думают, и я не могу проверить это на данный момент.

Ответы

Ответ 1

@код всегда выполняется в соответствии с здесь и здесь.

Блок A @наконец содержит код, который должно выполняться независимо от того, является ли исключение бросается или нет.

Ответ 2

Да. Как ни странно, так оно и есть. Я не уверен, почему, но я только что построил тест и попробовал несколько конфигураций и каждый раз, когда он это делал.

Здесь были конфиги:

  • Возврат в блок try: прекращено выполнение блока try и вызвано, наконец, выполнение
  • Вернитесь в блок try и вернитесь в конце: остановите выполнение try и остановите выполнение в блоке finally и весь метод.
  • Возврат в блок finally: работает как обычный возврат за пределы блока try/catch/finally.

Ответ 3

С определением RAI блок finally будет в любом случае выполнен с этой областью кода для конкретного ресурса.

Он имеет тесное значение с Object ~Destructor. Так же, как и объект ~Destructor, всегда выполняется, наконец, блок также выполняется.

Ответ 4

Да. Даже если в блоке catch есть Exception, будет выполнен finally.

Если вы знакомы с С++, просто подумайте finally как destructor для object. Когда будет выполняться состояние выражения внутри объекта, ~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