/ / La variable Inout establecida en UIAlertAction cierre no cambia el valor - ios, swift, cierres

Variable de entrada establecida en UIAlertAction el cierre no cambia el valor: ios, swift, cierres

Tengo una función con un inout parámetro: enabled: Bool El objeto al que me refiero (lo sé inout no es técnicamente una referencia ...) y la configuración con este método es una propiedad almacenada en un UIViewController var enabled = false

Tengo varios booleanos que desencadenan diferentes cosas, y quiero usar un método para configurarlos.

Entonces llamo al método:

self.determineEnabled(&self.enabled)

A continuación se muestra el código, y he usado comentarios para explicar lo que está sucediendo.

Código:

func determineEnabled(inout enabled: Bool) {

if enabled == false {
enabled = true
//self.enabled equals true now. This works. Its not in a closure...
} else {

let delete = UIAlertAction(title: "Disable", style: .Destructive, handler: { (action) -> Void in

enabled = false
print(self.enabled)
//This doesn"t work. the inout variable equals FALSE
//self.enabled equals true
//If I set self.enabled = false.. Then it works, but I"m using a method because my app could have dozens of these enabled bools on this view controller.

let alertController = UIAlertController(title: "Change Bool", message: "", preferredStyle: UIAlertControllerStyle.Alert)

alertController.addAction(delete)
self.presentViewController(alertController, animated: true, completion: nil)
}
}

Mi aplicación es obviamente más compleja que esta porción de código, pero puedo verificar que este problema existe dentro de esta tirada de código.

Seré honesto porque no entiendo los cierres tanto como quisiera.

Pero si puedo usar self.enabled para cambiar correctamente el valor de habilitado, ¿qué impide que Swift cambie la configuración de la variable habilitada inout?

ACTUALIZAR:

Aquí hay un enlace de los documentos que mencionan específicamente mi problema: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545

"No hay copia al final de los cierres ofunciones anidadas Esto significa que si se llama a un cierre después de que la función regrese, cualquier cambio que haga el cierre en los parámetros de entrada y salida no se copiará nuevamente al original ".

Evolución rápida sobre el tema: https://github.com/apple/swift-evolution/blob/master/proposals/0035-limit-inout-capture.md

Respuestas

3 para la respuesta № 1

En Swift, las funciones son cierres. Los cierres capturan el estado. En el momento nos encontramos con la función anónima que contiene el código print(self.enabled), self.enabled es true. Sabemos que, si no fuera así, no estaríamos aquí en absoluto (estaríamos en el primer ala de la condición, if enabled == false) Por lo tanto cuando print(self.enabled) luego se ejecuta, imprimirá true, porque ese era el estado de las cosas cuando capturó su valor.


2 para la respuesta № 2

Lo dijiste tú mismo en tu pregunta;

Sé que inout no es técnicamente una referencia

Del libro de Apple Swift

Un parámetro de entrada tiene un valor que se pasa en a la función, es modificado por la función y se devuelve fuera de la función para reemplazar el valor original.

Está modificando el valor en un cierre que se ejecuta algún tiempo después cuando el usuario interactúa con la alerta. En este punto determineEnabled ya ha devuelto y almacenado el valor de inout parámetro.

Si una inout parámetro estaba una referencia, como un puntero estilo C, luego enabled estaría apuntando a un trozo de memoria que almacena self.enabled y cuando el valor se modificó en el cierre, self.enabled sería modificado

Puede ver cómo funciona esto si crea una clase simple con una propiedad booleana y luego pasa una instancia de esta clase a su determineEnabled función (sin usar inout) Ya que los objetos son pasado por referencia, una actualización posterior a la propiedad del objeto en el cierre será visible en cualquier lugar donde se use la misma referencia de objeto;