2009-02-12 10 views
24

Sono nuovo di Cocoa/Cocoa Touch e sto lavorando a un libro di sviluppo. Mi sono imbattuto in situazioni in cui viene utilizzato l'operatore @selector(). Sono un po 'perso su come e quando si dovrebbe usare l'operatore @selector(). Qualcuno può fornire una spiegazione breve e dolce e un esempio del perché è usato e quali benefici dà allo sviluppatore?Spiegazione dell'uso di Cocoa @selector

proposito, ecco codice campione prelevato dal terreno iPhone di Apple che utilizza @selector()

if ([elementName isEqualToString:@"entry"]) 
{ 

    parsedEarthquakesCounter++; 

    // An entry in the RSS feed represents an earthquake, so create an instance of it. 
    self.currentEarthquakeObject = [[Earthquake alloc] init]; 
    // Add the new Earthquake object to the application's array of earthquakes. 
    [(id)[[UIApplication sharedApplication] delegate] 
      performSelectorOnMainThread:@selector(addToEarthquakeList:) 
      withObject:self.currentEarthquakeObject waitUntilDone:YES]; 
    return; 
} 
+0

possibile duplicato di [? Come SEL e il lavoro @selector nel SDK iPhone] (http://stackoverflow.com/questions/297680/how-do- sel-selector-work-in-iphone-sdk) – Monolo

risposta

40

L'operatore selettore fornisce un modo per fare riferimento a un metodo fornito da un oggetto, in qualche modo simile a un puntatore a funzione in C. È utile perché consente di disaccoppiare il processo di chiamare i metodi su un oggetto. Ad esempio un pezzo di codice potrebbe fornire un metodo, e un altro pezzo di codice potrebbe applicare quel metodo a un determinato insieme di oggetti.

Esempi:

test per vedere se un oggetto implementa un certo metodo:

[object respondsToSelector:@selector(methodName)] 

Conservare un metodo da chiamare in seguito su un oggetto;

SEL method = @selector(methodName); 
[object performSelector:method]; 

Chiama un metodo su un thread diverso (utile per il lavoro della GUI).

[object performSelectorOnMainThread:@selector(methodName)] 
+3

Grazie per la spiegazione: puoi dare un esempio del perché lo utilizzi invece di chiamare un metodo nel modo convenzionale, assumendo che tu sappia che l'oggetto supporta quel metodo ? – lupefiasco

+9

@lupefiasco: [object performSelectorInBackground: @selector (methodName)] comporterà una chiamata asincrona al metodo. – codelogic

+10

Un altro caso d'uso è se si ha il nome del selettore come una stringa, quindi si può fare, in fase di esecuzione, qualcosa come [object performSelector: NSSelectorFromString (qualcosa) ...] – codelogic

2

@selector() viene utilizzato ogni volta che è necessario passare il nome di un metodo come argomento di un altro metodo, una funzione o come valore variabile. Passare direttamente il nome non funziona nell'obiettivo-C.

4

In aggiunta a ciò che è stato detto, è anche possibile concludere la @selector in un NSInvocation per un uso successivo. È possibile impostare gli argomenti su NSInvocation molto tempo dopo la sua creazione e attivarlo quando è necessario far scattare il messaggio. Questo ti dà un sacco di potere.

Per un'introduzione al concetto, Scott Stevenson ha un ottimo post intitolato "Dynamic Objective-C with NSInvocation".

2

Un esempio pratico è il metodo validateMenuItem in cui le voci di menu sono identificate con le azioni di destinazione.

esempio semplificato:

- (BOOL)validateMenuItem:(NSMenuItem *)item { 
    if ([item action] == @selector(selectFiles:) && otherCondition) { 
     return YES; 
    } else { 
     return NO; 
    } 
} 
0

È possibile utilizzare un selettore per richiamare un metodo su un oggetto, questo fornisce la base per la realizzazione del modello di obiettivo-azione in Cocoa.

[myObject performSelector:@selector(runMYmethod:) withObject:parameters]; 

è equivalente a:

[myObject runMYmethod:parameters];