and xcode escaping closures swift3

xcode - and - Actualización de cierres a Swift 3-@escaping



swift @escaping and completion handler (2)

He actualizado mi código a Xcode 8.0 beta 6, pero me quedé atrapado con lo que parece ser sobre el nuevo cierre predeterminado sin escape. En el siguiente código, Xcode sugiere agregar @escaping de la completion: en la primera línea del código a continuación, pero eso aún no se compila y va en círculos. * *

( EDITAR : de hecho, @escaping debe agregarse después de la completion: como sugiere Xcode. La alerta aún puede mostrarse, pero la limpieza y la compilación lo eliminarán). * ¿Cómo debe reescribirse / repararse este código para que funcione en la versión actualizada? Swift 3? He echado un vistazo al nuevo manual, pero no pude encontrar ejemplos de código adecuados.

func doSomething(withParameter parameter: Int, completion: () -> ()) { // Does something callSomeOtherFunc(withCompletion: completion) } // Calling the method and execute closure doSomething(withParameter: 2) { // do things in closure }

Cualquier ayuda muy apreciada!


@noescape

Desde xcode 8 beta 6 @noescape es el valor predeterminado. Antes de eso, @escaping era el valor predeterminado. Cualquiera que actualice a Swift 3.0 desde versiones anteriores podría enfrentar este error.

No puede almacenar un cierre @noescape dentro de una variable. Porque si puede almacenar un cierre dentro de una variable, puede ejecutar el cierre desde cualquier parte de su código. Pero @noescape afirma que el parámetro de cierre no puede escapar del cuerpo de la función.

Esto dará un error del compilador en Xcode 8

class MyClass { var myClosure: (() -> ())? func doSomething(finishBlock: () -> ()) { myClosure = finishBlock // ‼️ Error: Assigning non-escaping parameter ''finishBlock'' to an @escaping closure } }

Esto compilará bien (explícitamente escriba @escaping )

class MyClass { var myClosure: (() -> ())? func doSomething(finishBlock: @escaping () -> ()) { myClosure = finishBlock } }

Beneficios de @noescape :

  • El compilador puede optimizar su código para un mejor rendimiento
  • El compilador puede encargarse de la gestión de la memoria.
  • No hay necesidad de usar una referencia débil de uno mismo en el cierre


Para obtener más información, consulte: Establecer cierres sin escape como predeterminados


Swift 3: los atributos del parámetro de cierre ahora se aplican al tipo de parámetro, y no al parámetro en sí

Antes de Swift 3, los atributos de cierre @autoclosure y @noescape solían ser atributos para el parámetro de cierre, pero ahora son atributos para el tipo de parámetro; ver la siguiente propuesta de evolución Swift aceptada:

Su pregunta específica se refiere al atributo de tipo de parámetro @escaping (para el cual se aplica la misma nueva regla), como se describe en la propuesta de evolución Swift aceptada para permitir que los parámetros de cierre no escapen de forma predeterminada:

Estas propuestas ahora se implementan en la etapa beta de Xcode 8 (consulte las notas de la versión de Xcode 8 beta 6 ; se necesita iniciar sesión en la cuenta de desarrollador para acceder)

Nuevo en Xcode 8 beta 6 - Compilador Swift: lenguaje Swift

Los parámetros de cierre no escapan de forma predeterminada, en lugar de anotarse explícitamente con @noescape . Use @escaping para indicar que un parámetro de cierre puede escapar. @autoclosure(escaping) ahora se escribe como @autoclosure @escaping . Las anotaciones @noescape y @autoclosure(escaping) están en desuso. (SE-0103)

...

Nuevo en Xcode 8 beta - Compiladores Swift y Apple LLVM: lenguaje Swift

Los @noescape y @autoclosure ahora deben escribirse antes del tipo de parámetro en lugar de antes del nombre del parámetro. [SE-0049]

Por lo tanto, utiliza el atributo @escaping no predeterminado de la siguiente manera; aplicado al tipo del parámetro de cierre, en lugar del parámetro en sí

func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) { // ... }

(Incluyendo mi respuesta a una pregunta en un comentario votado a continuación, ya que los comentarios no son datos persistentes sobre SO)

@Cristi Băluță: "¿Qué hace el escape? Nunca he visto estas palabras clave antes de la conversión automática swift3 ..."

Consulte, por ejemplo, el enlace a la propuesta de evolución SE-0103 anterior (así como el texto citado de las notas de la versión beta 6): anteriormente, los parámetros de cierre escapaban por defecto (por lo tanto, no es necesario que exista una anotación explícita para escapar), pero ahora, en cambio, no escapan, por defecto. De ahí la adición de @escaping para anotar explícitamente que un parámetro de cierre puede escapar (contrario a su comportamiento predeterminado). Esto también explica por qué @noescape ahora está en desuso (no es necesario anotar el comportamiento predeterminado).

Para explicar lo que significa que se está escapando un parámetro de cierre, cito la Referencia del lenguaje: atributos :

"Aplique este atributo al tipo de un parámetro en una declaración de método o función para indicar que el valor del parámetro se puede almacenar para una ejecución posterior. Esto significa que el valor puede sobrevivir a la duración de la llamada".