2012-05-25 16 views
8

Ho letto molti articoli per capire perché è necessario utilizzare @selector() per fare riferimento a un metodo, ma non penso di essere soddisfatto. Quando specifichiamo un'azione per un pulsante, ad esempio, dobbiamo scrivere:Per che cosa è la direttiva @selector? Perché non usare semplicemente il nome del metodo?

[btn addTarget:self action:@selector(myMethod)]; 

Perché non semplicemente:

[btn addTarget:self action:myMethod]; 

Si prega di spiegare la necessità e la ragione, e cosa succede senza di essa.

+0

Questo perché in Objective-C che abbiamo di messaggi non metodo chiamante ... –

+1

Perfettamente domanda valida e, finora, nessuna delle risposte tocca la vera ragione (anche se hanno tutte fornito buone ragioni per le quali i selettori vengono utilizzati in primo luogo. – bbum

risposta

8

Ho letto molti articoli per comprendere la parola chiave @selector ma non ho ancora capito il suo scopo. Voglio solo chiedere perché abbiamo @selector.

Tutto ha a che fare con l'analisi del linguaggio C.

Di per sé, in un'espressione come [obj performSelector:someRandomSelector]' il compilatore tratta i someRandomSelector po 'come "espandere qualunque someRandomSelector è - la valutazione delle espressioni, si occupano di #defines, che stabilisce un simbolo per dopo il collegamento, ecc ... - e qualunque che produce espansione meglio essere SEL.

Quindi, se si dovesse scrivere [obj performSelector:action]' compilatore avrebbe alcun modo di sapere la differenza tra action come variabile contenente un selettore potenzialmente volatile e action essere il nome effettivo di un metodo su obj.

@selector() risolve questo creando un'aggiunta sintattica al linguaggio che valuta sempre un risultato SEL costante.

Storicamente, Objective-C è stato originariamente implementato come estensione diretta al preprocessore C. Tutte le varie aggiunte prefissate di @... hanno reso l'implementazione molto più semplice in quanto sostanzialmente qualsiasi cosa preceduta da un @ era un Objective-Cism.

0
+0

In realtà, i selettori * do * persistono durante il runtime in Objective-C e un selettore è essenzialmente una stringa C univoca internamente. –

+0

Ok, ho cancellato la mia spiegazione maldestra, e mi limiterò a collegarmi ai documenti. – woz

1

È una questione di design della lingua. Hai bisogno di qualcosa da dire 'questo è un selettore' e questa è la sintassi utilizzata per separare il testo nel file sorgente che descrive il selettore di cui stai parlando e il codice che lo circonda. Ciò richiede un qualche tipo di citazione o parentesi attorno ad esso. @selector(...) è solo la sintassi con cui sono andati.

E se avessi un selettore che contiene :, ad esempio chiamato thingWithX:y:z:? Non hai [btn addTarget:self action:thingWithX:y:z:] dato che i due punti confondono il compilatore. Dovresti avere [btn addTarget:self action:@selector(thingWithX:y:z:)] in modo da poter separare il selettore di btn action: e il selettore a cui fa riferimento `thingWithX:y:z:.

0

Il vostro esempio può funzionare, se myMethod è un'istanza di SELEZIONE

[btn addTarget:self action:myMethod]; 

Per stringa è possibile utilizzare

[btn addTarget:self action:NSSelectorFromString(@"myMethod")]; 

spiegato qui https://developer.apple.com/library/mac/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Ecco un esempio di un'actionLinker generica function How to programmatically setup a CallBacks for a UIButton?

- (void)setRunButton:(UIButton *)objectName mySelector:(NSString *)action myControlEvent:(UIControlEvents)controlEvent { 

    [objectName addTarget:self action:NSSelectorFromString(action) forControlEvents:controlEvent]; 

} 

se si desidera utilizzare il proprio esempio con myMethod come un esempio di selettore, seguente codice è più applicabile

- (void)setRunButton:(UIButton *)objectName mySelector:(SEL)action myControlEvent:(UIControlEvents)controlEvent { 

    [objectName addTarget:self action:action forControlEvents:controlEvent]; 

}