2014-06-09 3 views
23

Per la maggior parte, Swift rappresenta un enorme miglioramento rispetto all'Obiettivo-C in termini di sicurezza del tipo. Un'eccezione eclatante sono i selettori. In Objective-C, utilizzando l'espressione @selector(notARealSelector:) verrà visualizzato un avviso del compilatore. L'equivalente Swift, Selector("notARealSelector:") verrà sempre compilato ma non riuscirà in fase di esecuzione.Esiste un modo tipicamente valido per utilizzare i selettori in Swift?

C'è un modo tipicamente valido per utilizzare i selettori in Swift, quindi posso lavorare con API Objective-C che li richiedono?

Ho un sacco di osservatori NSNotification nella mia app e vorrei avere qualche tipo di controllo in fase di compilazione che non sto facendo errori di battitura nei miei selettori.

Modifica: il caso d'uso specifico è NSNotificationCenter.addObserver.

+0

Può fare un esempio di come si sta utilizzando il Il blocco '@selector()' al momento? Gli oggetti che stai chiamando questi metodi espongono (tramite la conformità al protocollo o la sottoclassi) i metodi in qualsiasi momento? Puoi usare 'myDelegate? .scrollViewDidScroll? (...)', ma ciò richiede che il delegato sia almeno conforme al protocollo, in modo che il compilatore abbia una possibilità di determinare se è possibile che anche quel metodo sia lì. –

+0

Come ho detto nella domanda, 'NSNotificationCenter.addObserver' – Bill

+0

Un altro uso comune di @selector è il target/azione utilizzato da' UIControl' e sottoclassi. per esempio. 'button.addTarget (self, action:" doTap ", forControlEvents: .TouchUpInside)' - frustrante che il compilatore rapido non possa avvisare di errori dovuti a errori di digitazione o modifica dei nomi dei metodi. –

risposta

3

selettori tipizzate sono stati appena pubblicato in Xcode 7.3 beta 4:

let sel = #selector(insertSubview(_:aboveSubview:)) // sel has type 

Selector ora è un primo cittadino di classe e viene fornito con alcune belle avvisi del compilatore Swift. Se necessario si può ancora passare in una stringa:

let sel = Selector("propertyName") 

Vedere una risposta molto più completo qui: @selector() in Swift? Note

Xcode Stampa: http://adcdownload.apple.com/Developer_Tools/Xcode_7.3_beta_4/Xcode_7.3_beta_4_Release_Notes.pdf

+0

Eccellente - grazie per avermelo fatto sapere! – Bill

+1

@Bill Vedi anche la mia discussione qui: http://stackoverflow.com/a/35658335/341994 Questo spiega a fondo la nuova sintassi '# selector'. Ci sono voluti solo, per esempio, due anni da quando tu (giustamente) hai fatto la tua domanda per inventare questo ... :) A mio avviso questo buco nella sicurezza del tipo è stato, per tutto questo tempo, un'enorme contraddizione di tutto ciò Swift dovrebbe rappresentare. Ora il buco è stato riempito. – matt

1

Utilizzare la nozione di Swift optional come:

if let result = object.notARealSelector?(/* args */) { 
    // Use Result 
} 

dove la ? utilizzato dopo notARealSelector con ritorno false a if quando non esiste un metodo definito sul tipo di object.

C'è un avvertimento per optional protocol requirements:

requisiti del protocollo opzionali possono essere specificati solo se il protocollo è contrassegnato con l'attributo @objc. Anche se non si interagisce con Objective-C, , è necessario contrassegnare i protocolli con l'attributo @objc se si desidera specificare i requisiti opzionali .

Ma dal momento che stai chiedendo in primo luogo ai metodi opzionali, devi parlare di questo nel contesto Objective-C.

+0

Sì, come ho detto nella domanda, sto cercando di passare i selettori a 'NSNotificationCenter' – Bill

+2

Inoltre, il trattamento di una funzione come facoltativo funziona solo con metodi di protocollo opzionali - non è possibile eseguire 'object.notARealSelector' a meno che' object' sia una variabile/costante di tipo di protocollo e detto protocollo sia un protocollo '@ obcj' che dichiara' notARealSelector' come metodo '@ opzionale'. – rickster

-1

È possibile utilizzare la riflessione per ottenere i nomi delle proprietà di un oggetto come stringhe, come riassunto in this answer, ma che non renderà la connessione tra un identificatore e il suo nome di stringa il modo in cui @selector fa in ObjC. Un certo uso creativo della riflessione potrebbe aggirare questo problema, ma potresti anche fare bene a file a bug.

Problemi correlati