2010-04-20 25 views
10

Qualcuno può chiarirmi sulle differenze tra le due affermazioni qui sotto.Utilizzo di [metodo automatico] o @selector (metodo)?

[self playButtonSound]; 

E:

[self performSelector:@selector(playButtonSound)]; 

sto solo chiedendo come ho avuto qualche vecchio codice che utilizza @selector, ora con un po 'più di conoscenza non riesco a capire perché non ho usato [self playButtonSound] invece, entrambi sembrano fare lo stesso come scritto qui.

Gary

+0

Grazie, ho capito ora, molto apprezzato. – fuzzygoat

+1

Van: perché hai eliminato, questo è utile no? Faranno sicuramente la stessa cosa. Una piccola differenza è che il primo esempio invierà un messaggio, playButtonSound; il secondo invierà due messaggi, first performSelector :, che invierà quindi playButtonSound. Vado sempre per la prima opzione a meno che tu non abbia scelta, se non altro per la leggibilità. – fuzzygoat

risposta

10

Sia per la stessa cosa, ma [self playButtonSound]; è sicuramente il modo normale per invocare un metodo in Objective-C. Tuttavia, l'utilizzo di performSelector: consente di chiamare un metodo determinato solo in fase di esecuzione.

Dal NSObject Protocol Reference:

Il performSelector: metodo è equivale ad inviare un messaggio di aSelector direttamente al ricevitore. Ad esempio, tutti e tre i seguenti messaggi fanno la stessa cosa:

id myClone = [anObject copy]; 
id myClone = [anObject performSelector:@selector(copy)]; 
id myClone = [anObject performSelector:sel_getUid("copy")]; 

Tuttavia, il metodo performSelector: consente di inviare messaggi che non sono determinate fino al runtime. Un selettore variabile può essere passato come argomento :

SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation(); 
[anObject performSelector:myMethod]; 
+1

Inciampato su questa risposta e roba imparata! Grazie! – Groot

6
[self playButtonSound]; 

Qui compilatore controllerà se l'oggetto risponde a -playButtonSound messaggio e vi darà un avvertimento se non lo fa.

[self performSelector:@selector(playButtonSound)]; 

Calling -playButtonSound in questo modo non sarà possibile ottenere avviso del compilatore. Tuttavia è possibile controllare dinamicamente se gli oggetti rispondono a un determinato selettore - in modo da poter tranquillamente tentare di chiamare un selettore arbitrario su un oggetto senza specificarne il tipo e non ricevere gli avvertimenti del compilatore (che può essere utile ad esempio per chiamare metodi facoltativi in ​​un oggetto delegato) :

if ([self respondsToSelector:@selector(playButtonSound)]) 
    [self performSelector:@selector(playButtonSound)]; 
+0

C'è una parentesi mancante nella riga 'if ([self respondsToSelector: @selector (playButtonSound)]' -it dovrebbe essere 'if ([self respondsToSelector: @selector (playButtonSound)])'. –

+2

In realtà, puoi avere il compilatore lanciare un avviso ai selettori non dichiarati aggiungendo -Wundeclared-selector nel campo Altre flag di avviso nelle impostazioni di generazione.Trovato che sia molto utile. –

Problemi correlati