web-dev-qa-db-fra.com

comment appeler une méthode d'arguments multiples avec délai

J'essaie d'appeler une méthode après un certain délai.

Je sais qu'il existe une solution pour cela:

[self performSelector:@selector(myMethod) withObject:nil afterDelay:delay];

J'ai vu cette question et Documentation

Mais ma question est: comment puis-je appeler une méthode qui prend deux paramètres?

par exemple:

- (void) MoveSomethigFrom:(id)from To:(id)to;

Comment pourrais-je appeler cette méthode avec delay, en utilisant performSelector:withObject:afterDelay:

Merci

39
Frade

use dispatch_after:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    //code to be executed on the main queue after delay
    [self MoveSomethingFrom:from To:to];
});

EDIT 2015: Pour Swift, je vous recommande d’utiliser cette méthode de petite assistance: dispatch_after - GCD in swift?

112
Martin Ullrich

Vous pouvez également implémenter une méthode dans la catégorie de NSObject en utilisant l'objet NSInvocation (fonctionne dans toutes les versions d'iOS). Je suppose que ça devrait être quelque chose comme ça:

@interface NSObject(DelayedPerform)

- (void)performSelector:(SEL)aSelector withObject:(id)argument0 withObject:(id)argument1  afterDelay:(NSTimeInterval)delay {

  NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];

  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  [invocation setTarget:self];
  [invocation setSelector:aSelector];
  [invocation setArgument:&argument0 atIndex:2];
  [invocation setArgument:&argument1 atIndex:3];

  [invocation performSelector:@selector(invoke) withObject:nil afterDelay:delay];

}

@end
7
Eldar Markov

Rapide:

    let delayInSeconds = 3.0;
    let delay = delayInSeconds * Double(NSEC_PER_SEC)
    let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay));
    dispatch_after(popTime, dispatch_get_main_queue(), {
        // DO SOMETHING AFTER 3 sec
    });
2
Alexander Volkov

Voici comment déclencher un blocage après un délai dans Swift:

runThisAfterDelay(seconds: 5) { () -> () in
    print("Prints this 5 seconds later in main queue")
    //Or perform your selector here
}

/// EZSwiftExtensions
func runThisAfterDelay(seconds seconds: Double, after: () -> ()) {
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue(), after)
}

Le nombre d'arguments n'a pas vraiment d'importance.

Il est inclus en tant que fonction standard dans mon référentiel: https://github.com/goktugyil/EZSwiftExtensions

1
Esqarrouth

Celles-ci fonctionneront toutes, mais sont toutes beaucoup plus complexes que nécessaire.

Concevez la méthode à appeler avec un argument NSDictionary. Mettez les objets dont vous avez besoin. 

Si vous souhaitez également que la méthode soit accessible par d'autres moyens, appelez plutôt une méthode qui "décompresse" le dictionnaire et appelle la méthode souhaitée avec des paramètres explicites. 

0
tooluser