91 votes

iOS - Comment mettre en place un performSelector avec plusieurs arguments et afterDelay?

Je suis un iOS débutant. J'ai un sélecteur de méthode comme suit -

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second
{

}

Je suis en train de mettre en place quelque chose comme ça -

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second" afterDelay:15.0];

Mais cela me donne une erreur en disant: -

Instance method -performSelector:withObject:withObject:afterDelay: not found

Toutes les idées de ce que je suis absent?

146voto

valvoline Points 2358

Personnellement, je pense que le plus proche de la solution à vos besoins est l'utilisation de NSInvocation.

Quelque chose comme ce qui suit va faire le travail:

indexPath et de la source de données sont deux variables d'instance défini de la même méthode.

SEL aSelector = NSSelectorFromString(@"dropDownSelectedRow:withDataSource:");

if([dropDownDelegate respondsToSelector:aSelector]) {
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[dropDownDelegate methodSignatureForSelector:aSelector]];
    [inv setSelector:aSelector];
    [inv setTarget:dropDownDelegate];

    [inv setArgument:&(indexPath) atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
    [inv setArgument:&(dataSource) atIndex:3]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation

    [inv invoke];
}

96voto

Michael Dautermann Points 47757

Car il n'y a pas une telle chose comme un [NSObject performSelector:withObject:withObject:afterDelay:] méthode.

Vous avez besoin d'encapsuler les données que vous voulez envoyer dans un unique Objectif C de l'objet (par exemple un NSArray, un NSDictionary, certains personnalisée Objectif de type C) et le passer à travers l'[NSObject performSelector:withObject:afterDelay:] méthode qui est bien connu et aimé.

Par exemple:

NSArray * arrayOfThingsIWantToPassAlong = 
    [NSArray arrayWithObjects: @"first", @"second", nil];

[self performSelector:@selector(fooFirstInput:) 
           withObject:arrayOfThingsIWantToPassAlong  
           afterDelay:15.0];

34voto

Firoze Lafeer Points 13596

Vous pouvez emballer vos paramètres en un seul objet et utiliser une méthode d'aide à l'appel de votre méthode originale comme Michael, et d'autres, ont suggéré.

Une autre option est dispatch_after, qui va prendre un bloc et mettre en file d'attente à un certain moment.

double delayInSeconds = 15.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

    [self fooFirstInput:first secondInput:second];

});

Ou, comme vous l'avez déjà découvert, si vous n'avez pas besoin du retard, vous pouvez utiliser - performSelector:withObject:withObject:

7voto

aroth Points 28424

L'option la plus simple est de modifier votre méthode pour prendre un paramètre unique contenant à la fois des arguments, comme par exemple un NSArray ou NSDictionary (ou ajouter une deuxième méthode qui prend un seul paramètre, le déballe, et appelle la première méthode, puis d'appeler la deuxième méthode sur un retard).

Par exemple, vous pourriez avoir quelque chose comme:

- (void) fooOneInput:(NSDictionary*) params {
    NSString* param1 = [params objectForKey:@"first"];
    NSString* param2 = [params objectForKey:@"second"];
    [self fooFirstInput:param1 secondInput:param2];
}

Et puis, vous pouvez le faire:

[self performSelector:@selector(fooOneInput:) 
      withObject:[NSDictionary dictionaryWithObjectsAndKeys: @"first", @"firstParam", @"second", @"secondParam", nil] 
      afterDelay:15.0];

6voto

Mike Wallace Points 181
- (void) callFooWithArray: (NSArray *) inputArray
{
    [self fooFirstInput: [inputArray objectAtIndex:0] secondInput: [inputArray objectAtIndex:1]];
}


- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second
{

}

et de l'appeler avec:

[self performSelector:@selector(callFooWithArray) withObject:[NSArray arrayWithObjects:@"first", @"second", nil] afterDelay:15.0];

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