web-dev-qa-db-fra.com

Création d'un sélecteur à partir d'un nom de méthode avec des paramètres

J'ai un exemple de code qui obtient un SEL de l'objet actuel,

SEL callback = @selector(mymethod:parameter2);

Et j'ai une méthode comme

 -(void)mymethod:(id)v1 parameter2;(NSString*)v2 {
}

Maintenant, je dois déplacer mymethod vers un autre objet, disons myDelegate.

J'ai essayé:

SEL callback = @selector(myDelegate, mymethod:parameter2);

mais il ne compilera pas.

57
BlueDolphin

SEL est un type qui représente un sélecteur dans Objective-C. Le mot clé @selector () renvoie un SEL que vous décrivez. Ce n'est pas un pointeur de fonction et vous ne pouvez lui passer aucun objet ou référence de quelque nature que ce soit. Pour chaque variable du sélecteur (méthode), vous devez le représenter dans l'appel à @selector. Par exemple:

-(void)methodWithNoParameters;
SEL noParameterSelector = @selector(methodWithNoParameters);

-(void)methodWithOneParameter:(id)parameter;
SEL oneParameterSelector = @selector(methodWithOneParameter:); // notice the colon here

-(void)methodWIthTwoParameters:(id)parameterOne and:(id)parameterTwo;
SEL twoParameterSelector = @selector(methodWithTwoParameters:and:); // notice the parameter names are omitted

Les sélecteurs sont généralement transmis aux méthodes déléguées et aux rappels pour spécifier la méthode à appeler sur un objet spécifique lors d'un rappel. Par exemple, lorsque vous créez un minuteur, la méthode de rappel est spécifiquement définie comme:

-(void)someMethod:(NSTimer*)timer;

Ainsi, lorsque vous planifiez le minuteur, vous utilisez @selector pour spécifier la méthode sur votre objet qui sera réellement responsable du rappel:

@implementation MyObject

-(void)myTimerCallback:(NSTimer*)timer
{
    // do some computations
    if( timerShouldEnd ) {
      [timer invalidate];
    }
}

@end

// ...

int main(int argc, const char **argv)
{
    // do setup stuff
    MyObject* obj = [[MyObject alloc] init];
    SEL mySelector = @selector(myTimerCallback:);
    [NSTimer scheduledTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES];
    // do some tear-down
    return 0;
}

Dans ce cas, vous spécifiez que l'objet obj doit être envoyé avec myTimerCallback toutes les 30 secondes.

100
Jason Coco

Vous ne pouvez pas passer un paramètre dans un @selector ().

Il semble que vous essayez d'implémenter un rappel. La meilleure façon de le faire serait quelque chose comme ceci:

[object setCallbackObject:self withSelector:@selector(myMethod:)];

Ensuite, dans la méthode setCallbackObject: withSelector: de votre objet: vous pouvez appeler votre méthode de rappel.

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector {
    [anObject performSelector:selector];
}
18
Grant Limberg

Au-delà de ce qui a déjà été dit sur les sélecteurs, vous voudrez peut-être regarder la classe NSInvocation.

n NSInvocation est un message Objective-C rendu statique, c'est-à-dire qu'il s'agit d'une action transformée en objet. Les objets NSInvocation sont utilisés pour stocker et transférer des messages entre des objets et entre des applications, principalement par des objets NSTimer et les objets distribués. système.

n objet NSInvocation contient tous les éléments d'un message Objective-C: une cible, un sélecteur, des arguments et la valeur de retour. Chacun de ces éléments peut être défini directement et la valeur de retour est définie automatiquement lorsque NSInvocation l'objet est distribué.

Gardez à l'esprit que bien qu'il soit utile dans certaines situations, vous n'utilisez pas NSInvocation dans une journée normale de codage. Si vous essayez simplement de faire en sorte que deux objets se parlent, envisagez de définir un protocole de délégué formel ou informel, ou de passer un sélecteur et un objet cible comme cela a déjà été mentionné.

5
Marc Charbonneau