2010-06-03 15 views
15

Considere el siguiente código:¿El código finalmente se ejecuta después de un retorno en Objective-C?

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

Si something no es válida y regreso desde dentro de la oportunidad, no el código en @finally ejecutar o no? Creo que debería hacerlo, pero otros con los que he hablado no piensan así y no puedo probar esto en este momento.

Respuesta

14

@finally code siempre se ejecuta de acuerdo con here y here.

Un bloque de código que contiene @finally debe ser ejecutado si una excepción es lanzada o no.

4

Sí. Curiosamente, lo hace. No estoy seguro de por qué, pero solo construí una prueba e intenté varias configuraciones y cada vez que lo hice.

aquí eran las configuraciones:

  • retorno en bloque try: se detuvo la ejecución del bloque try y causó finalmente a ser ejecutado
  • retorno en bloque try y volver por último: se detuvo la ejecución de la prueba y se detuvo la ejecución en bloque finalmente y todo el método.
  • Return in finally block: funcionó como el retorno normal fuera de un bloque try/catch/finally.
+2

El primer caso no es impar. Ese es el punto de 'finalmente'. Ver http://stackoverflow.com/questions/65035/in-java-does-return-trump-finally. – kennytm

+0

Verá, esperaría que 'return' fuera del alcance del bloque' try/catch/finally' y se aplique al método. No digo que esté mal que haga eso, pero ME ENCUENTRA desprevenido. Es algo a lo que nunca le había prestado atención. Creo que siempre llevé mis métodos hasta el final;) – lewiguez

1

Sí. Incluso si hubiera un Exception dentro del bloque catch, se ejecutará finally.

Si está familiarizado con C++, solo piense en finally como destructor de object. Cualquiera que sea el estado de una declaración dentro del objeto, ~Destructor se ejecutará. Pero no puede poner return dentro de finally [aunque algunos compiladores lo permiten].

Vea el código a continuación: Vea cómo se ha cambiado la variable global y. Vea también cómo Exception1 ha sido cubierto por 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(); 
     } 
    } 
} 

salida:

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

Con la definición RAI, último bloque de todos modos será ejecutado con ese ámbito de código, para en particular de los recursos.

Tiene un significado cercano con Object ~Destructor. Como siempre se ejecuta el objeto ~Destructor, finalmente también se ejecuta el bloqueo.

Cuestiones relacionadas