Question

Je sais comment créer un SEL au moment de la compilation en utilisant @selector (MyMethodName:) , mais ce que je veux faire est de créer un sélecteur de manière dynamique à partir d'un NSString . Est-ce même possible?

Ce que je peux faire:

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

Ce que je veux faire: (pseudo-code, cela ne fonctionne évidemment pas)

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

J'ai effectué une recherche dans la documentation de l'API Apple, mais je n'ai pas trouvé de solution qui ne repose pas sur la syntaxe de compilation @selector (myTarget:) .

Était-ce utile?

La solution

Je ne suis pas un programmeur Objective-C, mais simplement un sympathisant, mais peut-être NSSelectorFromString est ce dont vous avez besoin. C'est mentionné explicitement dans la Référence d'exécution que vous pouvez utiliser convertir une chaîne en sélecteur.

Autres conseils

Selon la documentation XCode, votre psuedocode comprend les choses correctement.

  

Il est plus efficace d’attribuer des valeurs aux variables SEL lors de la compilation à l’aide de la directive @selector (). Toutefois, dans certains cas, un programme peut avoir besoin de convertir une chaîne de caractères en sélecteur au moment de l'exécution. Cela peut être fait avec la fonction NSSelectorFromString:

setWidthHeight = NSSelectorFromString (aBuffer);

Edit: Bummer, trop lent. : P

Je dois dire que c'est un peu plus compliqué que les réponses des répondants précédents pourraient suggérer ... si vous voulez vraiment créer un sélecteur . .. pas seulement " appeler un " que vous avez "traîner" ...

Vous devez créer un pointeur de fonction qui sera appelé par votre " nouveau " method .. donc pour une méthode comme [self theMethod: (id) methodArg]; , vous écririez ...

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

et vous devez ensuite générer le bloc IMP de manière dynamique, cette fois en passant, "auto", le SEL , ainsi que tous les arguments ...

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

et ajoutez-le à votre classe, ainsi qu'une signature de méthode précise pour le meunier entier (dans ce cas, " v @: @ "" ), le renvoi void, l'appelant d'objet, l'argument d'objet)

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

Vous pouvez voir de bons exemples de ce type de manœuvres d'exécution , dans l'un de mes dépôts, ici.

Je sais qu’il ya une réponse à cette question depuis longtemps, mais je veux tout de même partager. Cela peut être fait en utilisant sel_registerName aussi.

L'exemple de code dans la question peut être réécrit comme ceci:

SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top