2016-03-22 18 views
36

Sto passando la sintassi del mio progetto verso Swift 2.2 (che xCode mi aiuta a fare automaticamente); tuttavia, non capisco la nuova sintassi #selector().Comprensione di Swift 2.2 Sintassi del selettore - #selector()

Per fare un esempio:

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

Questo è il selettore #selector(MyVC.timerCalled(_:))

Che cosa significa la _: significare? Puoi aggiungere altre variabili in questo selettore? Dì, #MyVC.timerCalled(_:whateverVar).

Le informazioni generali su ciò che è diverso in questa sintassi rispetto all'implementazione basata su stringhe dalle versioni precedenti di Swift sono molto apprezzate.

+2

Penso di spiegarlo bene qui: http://stackoverflow.com/questions/35658334/how-do-i-resolve-ambiguous-use-of-compile-error-with-swift-selector-syntax/35658335# 35658335 – matt

+0

La risposta di @ matt indirizza la sintassi più a fondo, compresa un'utile discussione sull'affrontare i metodi sovraccaricati. – Stuart

risposta

31

Il bit tra parentesi è un meccanismo per identificare la lista degli argomenti per il selettore che si desidera.

Vi consiglio di guardare la proposta Generalized Naming da Swift Evolution. Copre i casi in cui si dispone di un numero di funzioni che differiscono solo per le etichette dei parametri e che devono fare riferimento ad esse. L'esempio da questo documento è:

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

Se si voleva ottenere un valore di funzione per uno di quelli che il risultato è ambiguo:

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

La soluzione implementata è quella di aggiungere le etichette di argomento, senza alcuna digitare le informazioni per il codice che genera il valore della funzione per disambiguare cui si desidera:

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

Vedere come le etichette vengono aggiunte le parentesi?

Questa proposta ha avuto un ruolo in quello che si applica più direttamente alla tua domanda:

Referencing the Objective-C selector of a method

In questo caso particolare il selettore si desidera fare riferimento a è timerCalled: che è una funzione di un parametro che non ha etichetta Quindi (_ :). Il carattere di sottolineatura indica che l'etichetta non è specificata e i due punti.

8

Questo è il modo in cui le firme del metodo Swift sono rappresentate nella documentazione e ora sta iniziando a essere utilizzato in nuove funzionalità del linguaggio come la sintassi #selector() per esprimere i metodi tramite i loro elenchi di argomenti.

I due punti (:) rappresentano un parametro di metodo. Per i parametri denominati, i due punti sono preceduti dal nome del parametro esterno; per i parametri senza nome, viene utilizzato un trattino basso (_).

Così, per esempio, MyVC.timerCalled(_:)) indica un metodo del tipo MyVC con un parametro senza nome, che potrebbe essere dichiarato in questo modo:

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

(Si noti che timer è il nome del parametro interno, dal momento che per default il primo parametro di un metodo è senza nome)

Il tipo (MyVC nell'esempio) può anche essere omesso se rientra nello stesso ambito della dichiarazione #selector().

Un esempio più complesso potrebbe assomigliare a questo:

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

... 

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... } 
19

Swift 2.2 ha disattivato i selettori Stringificati: In swift 2.0, utilizziamo per scrivere il selettore come String i.e "buttonClicked". Lo svantaggio di questo approccio è che il compilatore non può verificare se il metodo esiste realmente o meno in fase di compilazione (anche se l'hai scritto in modo errato).

EX: 1

func buttonClicked(){ 
} 

Così il metodo di cui sopra nel nuovo approccio può essere chiamato come #selector(buttonClicked)

EX: 2

func buttonClicked(stringValue : String){ 
} 

Così il metodo di cui sopra in il nuovo approccio può essere chiamato come #selector(buttonClicked(_:))

EX: 3

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

Così il metodo di cui sopra con i parametri nel nuovo approccio può essere chiamato come #selector(buttonClicked(_:indexValue:))

+0

Ehi, ho appena letto questa domanda. Potresti per favore spiegarmi brevemente perché il compilatore avrebbe corretto/modificato l'esempio precedente in #selector (YourClass.buttonClicked) invece di solo #selector (buttonClicked) durante la conversione in swift 2.2. C'è una differenza tra il 2? Grazie – crashoverride777

+0

@ crashoverride777 penso che la tua domanda sia stata spiegata chiaramente qui. Http://stackoverflow.com/questions/24007650/selector-in-swift?rq=1 –

+0

Penso che tu abbia sempre bisogno di prefisso la dichiarazione del metodo con @objc – blackjacx

9

consideri sotto il codice per l'aggiunta di destinazione per il pulsante in rapida 3 utilizzando #selector

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

func buttonAction(sender:UIButton!){ 

} 

Questa sintassi ha funzionato per me durante la migrazione a rapida 3

+0

La domanda riguarda la VERSIONE 2 ... – FonzTech

Problemi correlati