Descripción de la sintaxis del selector Swift 2.2 - # selector()


Estoy cambiando la sintaxis de mi proyecto hacia Swift 2.2 (que xCode me ayuda a hacer automáticamente); sin embargo, no entiendo la nueva sintaxis #selector().

Como ejemplo:

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, 
             selector: #selector(MyVC.timerCalled(_:)), //new selector syntax!
             userInfo: nil, repeats: true)

Este tiene el selector #selector(MyVC.timerCalled(_:))

¿Qué significa el _:? ¿Puede agregar otras variables a este selector? Digamos, #MyVC.timerCalled(_:whateverVar).

La información general sobre lo que es diferente en esta sintaxis en comparación con la implementación basada en cadenas de versiones anteriores de Swift son en gran medida apreciar.

Author: Marcus Leon, 2016-03-23

4 answers

El bit entre paréntesis es un mecanismo para identificar la lista de argumentos para el selector que desea.

Te recomiendo que mires la propuesta de Generalized Naming de Swift Evolution. Cubre los casos en los que tiene una serie de funciones que difieren solo por sus etiquetas de parámetros y necesitan referirse a ellas. El ejemplo de ese documento es:

extension UIView {
  func insertSubview(view: UIView, at index: Int)
  func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
  func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
}

Si desea obtener un valor de función para uno de ellos, el resultado es ambiguo:

let fn = someView.insertSubview // ambiguous: could be any of the three methods

La solución implementado es agregar las etiquetas de argumento, sin ninguna información de tipo al código que genera el valor de la función a desambiguar que desea:

let fn = someView.insertSubview(_:at:)
let fn1 = someView.insertSubview(_:aboveSubview:)

¿Ves cómo se añaden las etiquetas en los paréntesis?

Esta propuesta jugó un papel en la que más directamente se aplica a su pregunta:

Referencia al selector Objective-C de un método

En este caso particular, el selector al que desea referirse es timerCalled: que es una función de un parámetro que no tiene etiqueta. Ahí (_:). El subrayado significa que la etiqueta no está especificada y los dos puntos.

 31
Author: Scott Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-22 22:27:50

Swift 2.2 tiene selectores Stringified obsoletos: En swift 2.0, usamos para escribir el selector como una cadena, es decir, "buttonClicked". La desventaja de este enfoque es que el compilador no puede verificar si el método realmente existe o no en tiempo de compilación(Incluso si lo ha escrito mal).

EX:1

func buttonClicked(){
}

Así que el método anterior en el nuevo enfoque se puede llamar como #selector(buttonClicked)

EX:2

func buttonClicked(stringValue : String){
}

Así que el método anterior en el nuevo enfoque se puede llamar como #selector(buttonClicked(_:))

EX:3

func buttonClicked(stringValue : String, indexValue : Int){
}

Así que el método anterior con parámetros en el nuevo enfoque se puede llamar como #selector(buttonClicked(_:indexValue:))

 19
Author: Durga Vundavalli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-29 09:36:55

Considere el siguiente código para agregar el objetivo al botón en swift 3 usando # selector

button.addTarget(self, action: #selector(self.buttonAction(sender:)),
                       for: UIControlEvents.touchUpInside)

 func buttonAction(sender:UIButton!){

 }

Esta sintaxis funcionó para mí al migrar a swift 3

 9
Author: Ankit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-06 08:05:29

Esta es la forma en que las firmas de los métodos Swift se representan en la documentación, y ahora está comenzando a usarse en nuevas características del lenguaje, como la sintaxis #selector() para expresar métodos mediante sus listas de argumentos.

Los dos puntos (:) representan un parámetro de método. Para los parámetros con nombre, los dos puntos están precedidos por el nombre del parámetro externo; para los parámetros sin nombre, se usa un guion bajo (_).

Así, por ejemplo, MyVC.timerCalled(_:)) indica un método en el tipo MyVC con uno sin nombre parámetro, que podría declararse así:

func timerCalled(timer: NSTimer) { ... }

(Tenga en cuenta que timer es el nombre del parámetro interno , ya que por defecto el primer parámetro de un método no tiene nombre)

El tipo (MyVC en su ejemplo) también se puede omitir si está dentro del mismo alcance de la declaración #selector().

Un ejemplo más complejo podría verse así:

let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:))

...

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... }
 8
Author: Stuart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-22 22:30:16