Selettori in Objective-C?


122

In primo luogo, non sono sicuro di capire veramente cosa sia un selettore. A quanto mi risulta, è il nome di un metodo e puoi assegnarlo a una classe di tipo "SEL" e quindi eseguire metodi come replyToSelector per vedere se il ricevitore implementa quel metodo. Qualcuno può offrire una spiegazione migliore?

In secondo luogo, a questo punto, ho il seguente codice:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

Tuttavia, anche se thingè chiaramente una sorta di NSString e dovrebbe rispondere a lowercaseString, non riesco a far sì che il condizionale "respondsToSelector" restituisca "YES" ...


Vuoi leggere la descrizione del selettore sul sito per sviluppatori Apple: Selettori .
lothar

14
Corso Stanford CS193P assegnazione 1B? Ho esattamente la stessa domanda qui! :)
Corstian Boerman

Risposte:


181

Devi stare molto attento ai nomi dei metodi. In questo caso, il nome del metodo è solo " lowercaseString", non " lowercaseString:" (notare l'assenza dei due punti). Ecco perché vieni NOrestituito, perché gli NSStringoggetti rispondono al lowercaseStringmessaggio ma non al lowercaseString:messaggio.

Come fai a sapere quando aggiungere i due punti? Aggiungi i due punti al nome del messaggio se vuoi aggiungere i due punti quando lo chiami, il che accade se richiede un argomento. Se richiede zero argomenti (come nel caso di lowercaseString), non ci sono due punti. Se richiede più di un argomento, devi aggiungere i nomi degli argomenti extra insieme ai loro due punti, come in compare:options:range:locale:.

È inoltre possibile esaminare la documentazione e notare la presenza o l'assenza di due punti finali.


12

I selettori sono un modo efficiente per fare riferimento ai metodi direttamente nel codice compilato: il compilatore è ciò che effettivamente assegna il valore a un SEL.

Altri hanno già coperto la seconda parte della tua q, il ':' alla fine corrisponde a una firma diversa da quella che stai cercando (in questo caso quella firma non esiste).


10

È perché vuoi @selector(lowercaseString), no @selector(lowercaseString:). C'è una sottile differenza: il secondo implica un parametro (nota i due punti alla fine), ma - [NSString lowercaseString]non accetta un parametro.


5

In questo caso, il nome del selettore è sbagliato. I due punti qui fanno parte della firma del metodo; significa che il metodo accetta un argomento. Credo che tu voglia

SEL sel = @selector(lowercaseString);

3

Il metodo di NSString è lowercaseString(0 argomenti), non lowercaseString:(1 argomento).


1

Non pensare ai due punti come parte del nome della funzione, pensalo come un separatore, se non hai nulla da separare (nessun valore da associare alla funzione), allora non ne hai bisogno.

Non sono sicuro del perché, ma tutta questa roba OO sembra essere estranea agli sviluppatori Apple. Suggerirei caldamente di prendere Visual Studio Express e di giocare anche con quello. Non perché uno sia migliore dell'altro, è solo un buon modo per esaminare i problemi di progettazione e il modo di pensare.

Piace

introspection = reflection
+ before functions/properties = static
- = instance level

È sempre utile esaminare un problema in modi diversi e la programmazione è il puzzle finale.


0

Dalla mia comprensione della documentazione Apple, un selettore rappresenta il nome del metodo che si desidera chiamare. La cosa bella dei selettori è che puoi usarli nei casi in cui il metodo esatto da chiamare varia. Come semplice esempio, puoi fare qualcosa come:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];

0

Come da documenti Apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Un selettore è il nome utilizzato per selezionare un metodo da eseguire per un oggetto o l'identificatore univoco che sostituisce il nome quando viene compilato il codice sorgente. Un selettore di per sé non fa nulla. Identifica semplicemente un metodo. L'unica cosa che rende il nome del metodo del selettore diverso da una semplice stringa è che il compilatore si assicura che i selettori siano univoci. Ciò che rende utile un selettore è che (insieme al runtime) agisce come un puntatore dinamico a funzione che, per un dato nome, punta automaticamente all'implementazione di un metodo appropriato per qualsiasi classe con cui viene utilizzato. Supponiamo di avere un selettore per il metodo eseguito e le classi Dog, Athlete e ComputerSimulation (ciascuna delle quali implementa un'esecuzione del metodo).

Esempio: (lldb) breakpoint --set selector viewDidLoad

Questo imposterà un punto di interruzione su tutte le implementazioni viewDidLoad nella tua app. Quindi il selettore è una specie di identificatore globale per un metodo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.