94 votes

Comment créer dynamiquement un sélecteur lors de l’exécution avec Objective-C ?

Je sais comment créer un au temps de compilation à l’aide mais ce que je veux faire, c’est créer un sélecteur dynamiquement depuis un `` . Est-ce encore possible ?

Ce que je peux faire :

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

J’ai cherché la documentation de l’API Apple, mais n’ont pas trouvé un moyen qui ne repose pas sur la compilation `` syntaxe.

180voto

Torsten Marek Points 27554

Je ne suis pas un Objectif-programmeur en C, un simple sympathisant, mais peut-être NSSelectorFromString est ce que vous avez besoin. Il est mentionné explicitement dans le Runtime de Référence que vous pouvez utiliser pour convertir une chaîne de caractères à un sélecteur.

40voto

Josh Gagnon Points 2264

Selon la documentation de XCode, votre psuedocode il est fondamentalement bonne.

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

``

Edit : Déception, trop lente. : P

14voto

alex gray Points 5089

Je dirais que c'est un peu plus compliquée que la précédente, les réponses des répondants pourrait suggérer... si vous voulez vraiment créer un sélecteur... et pas seulement "d'appeler l'un" que vous avez autour de la pose"...

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

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

et puis vous avez besoin de générer l' IMP bloc dynamiquement, cette fois, en passant, "auto", l' SEL, et de tous les arguments...

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

et l'ajouter à votre classe, avec une méthode précise de signature pour l'ensemble de la ventouse (dans ce cas - "v@:@", de retour void, objet de l'appelant, l'objet de l'argumentation)

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

Vous pouvez voir quelques bons exemples de ce type de runtime manigances, dans l'un de mes repos, ici.

5voto

Krypton Points 1578

Je sais cela a répondu pour longtemps, mais encore, je veux partager. Cela peut être fait en utilisant `` trop.

L’exemple de code dans la question peut être reformulée comme suit :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X