Actualización de cierres a Swift 3 – @escaping

He actualizado mi código a Xcode 8.0 beta 6 pero me quedé atascado con lo que parece ser el nuevo valor predeterminado de cierre que no escapa. En el siguiente código, Xcode sugiere agregar @escaping de completion: en la primera línea del código siguiente, pero que aún no se comstackrá y se irá en círculos. *

( EDITAR : De hecho, @escaping debería agregarse después de la completion: como sugiere Xcode. La alerta aún puede mostrarse, pero limpiarla y comstackrla la eliminará.) * ¿Cómo debe reescribirse / repararse este código para que funcione en la actualización? Swift 3? He echado un vistazo al nuevo manual pero no pude encontrar las muestras de código adecuadas.

 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!

Swift 3: los atributos de los parámetros 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 del parámetro de cierre, pero ahora son atributos del tipo de parámetro; vea la siguiente propuesta de evolución Swift aceptada:

  • SE-0049: Mueva @noescape y @autoclosure para que sean atributos de tipo

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

  • SE-0103: Hacer los cierres que no escapan por defecto

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 – Swift Compiler: Swift Language

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

Nuevo en Xcode 8 beta: Comstackdores LLVM de Swift y Apple: Swift Language

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 modificado abajo, ya que los comentarios no son datos persistentes en SO)

@Cristi Băluţă: “¿Qué hace escapando? Nunca he visto estas palabras clave antes de la conversión automática de swift3 …”

Véase, 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 escaparse), pero ahora están en cambio sin escape, por defecto. De ahí la adición de @escaping para anotar explícitamente que un parámetro de cierre puede escapar (al contrario de 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 un parámetro de cierre se está escapando, cito la Referencia del lenguaje – atributos :

“Aplique este atributo al tipo de parámetro en un método o statement de función para indicar que el valor del parámetro se puede almacenar para su posterior ejecución. Esto significa que se permite que el valor sobreviva a la duración de la llamada”.

@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 de @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 establece que el parámetro de cierre no puede escapar del cuerpo de la función.

Esto dará error de comstackción en Xcode 8

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

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

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

Beneficios de @noescape :

  • El comstackdor puede optimizar su código para un mejor rendimiento
  • El comstackdor puede encargarse de la gestión de la memoria
  • No es necesario usar una referencia débil a uno mismo en el cierre

Para obtener más información, consulte: hacer que los cierres que no escapan sean los predeterminados