Domanda

So come creare un SEL in fase di compilazione usando @selector (MyMethodName :) ma quello che voglio fare è creare un selettore in modo dinamico da un NSString . È anche possibile?

Cosa posso fare:

SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];

Cosa voglio fare: (codice pseudo, ovviamente non funziona)

SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];

Ho cercato i documenti dell'API di Apple, ma non ho trovato un modo che non si basi sulla sintassi @selector (myTarget :) in fase di compilazione.

È stato utile?

Soluzione

Non sono un programmatore di Objective-C, ma solo un simpatizzante, ma forse NSSelectorFromString è ciò di cui hai bisogno. È menzionato esplicitamente nella Riferimento runtime che puoi utilizzare per convertire una stringa in un selettore.

Altri suggerimenti

Secondo la documentazione di XCode, il tuo psuedocode praticamente funziona correttamente.

  

È più efficiente assegnare valori alle variabili SEL in fase di compilazione con la direttiva @selector (). Tuttavia, in alcuni casi, un programma potrebbe dover convertire una stringa di caratteri in un selettore in fase di esecuzione. Questo può essere fatto con la funzione NSSelectorFromString:

setWidthHeight = NSSelectorFromString (aBuffer);

Modifica: Bummer, troppo lento. : P

Dovrei dire che è un po 'più complicato di quanto potrebbero suggerire le risposte degli intervistati precedenti ... se davvero vuoi davvero creare un selettore . .. non solo " chiamane uno " che hai "messo in giro" " ...

Devi creare un puntatore a funzione che verrà chiamato dal tuo " nuovo " metodo .. quindi per un metodo come [self theMethod: (id) methodArg]; , dovresti scrivere ...

void (^impBlock)(id,id) = ^(id _self, id methodArg) { 
     [_self doSomethingWith:methodArg]; 
};

e quindi è necessario generare dinamicamente il blocco IMP , questa volta, passando, " self " ;, SEL e tutti gli argomenti ...

void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);

e aggiungilo alla tua classe, insieme a un'accurata firma del metodo per tutto il pollone (in questo caso " v @: @ " , ritorno vuoto, chiamante oggetto, argomento oggetto)

 class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");

Puoi vedere alcuni buoni esempi di questo tipo di shenanigans di runtime , in uno dei miei repository, qui.

So che questa è una risposta da molto tempo, ma voglio ancora condividerla. Questo può essere fatto anche usando sel_registerName .

Il codice di esempio nella domanda può essere riscritto in questo modo:

SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top