web-dev-qa-db-fra.com

Comment puis-je retarder un appel de méthode d'une seconde?

Y a-t-il un moyen facile de retarder un appel de méthode pendant 1 seconde?

J'ai un UIImageView qui réagit à un événement tactile. Lorsque le toucher est détecté, certaines animations se produisent dans l'application. Après une seconde, je veux appeler une autre méthode. Dans ce cas, je ne peux pas utiliser le sélecteur animationDidStop.

164
Thanks
performSelector:withObject:afterDelay:

référence du document

254
Jim

Vous pouvez aussi utiliser un bloc

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [object method]; 
});

La plupart du temps, vous voudrez utiliser dispatch_get_main_queue, bien que s'il n'y a pas d'interface utilisateur dans la méthode, vous pouvez utiliser un file d'attente globale .

Modifier:

Swift 3 version:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    object.method()
}

De même, DispatchQueue.global().asyncAfter(... pourrait également être une bonne option.

192
mcfedr

La meilleure façon de faire est:

[self performSelector:@selector(YourFunctionName) 
           withObject:(can be Self or Object from other Classes) 
           afterDelay:(Time Of Delay)];

vous pouvez également passer nil en tant que paramètre withObject.

exemple :

[self performSelector:@selector(subscribe) withObject:self afterDelay:3.0 ];
126
Milianoo

Il y a déjà beaucoup de réponses et elles sont toutes correctes. Si vous souhaitez utiliser le dispatch_after, vous devez rechercher l'extrait de code inclus dans le Code Snippet Library en bas à droite (où vous pouvez sélectionner les éléments UI.).

enter image description here

Il vous suffit donc d'appeler cet extrait en écrivant dispatch dans le code:

enter image description here

24
Alex Cio

Vous pouvez utiliser le sélecteur de performance après que la méthode de délai de 0,1 seconde soit appelée pour le code suivant.

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 
17
Nimit Parekh

Vous pouvez aussi:

[UIView animateWithDuration:1.0
                 animations:^{ self.view.alpha = 1.1; /* Some fake chages */ }
                 completion:^(BOOL finished)
{
    NSLog(@"A second lapsed.");
}];

Dans ce cas, vous devez simuler des modifications dans certaines vues pour que l'animation fonctionne. C'est hacky en effet, mais j'aime les trucs en bloc. Ou résumez la réponse @mcfedr ci-dessous.


waitFor(1.0, ^
{
    NSLog(@"A second lapsed");
});

typedef void (^WaitCompletionBlock)();
void waitFor(NSTimeInterval duration, WaitCompletionBlock completion)
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^
    { completion(); });
}
9
Geri

Tu peux le faire

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];
7
Nitesh

Swift 2.x

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
 dispatch_after(delayTime, dispatch_get_main_queue()) {
 print("do some work")
}

Swift 3.x - & - Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    print("do some work")
}

ou passer un escaping closure

func delay(seconds: Double, completion: @escaping()-> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: completion)
}
4
Salman Ghumsani

Il existe une solution Swift 3 de la solution vérifiée:

self.perform(#selector(self.targetMethod), with: self, afterDelay: 1.0)

Et il y a la méthode

@objc fileprivate func targetMethod(){

}
1
Kevin ABRIOUX

Utiliser dans Swift 3

perform(<Selector>, with: <object>, afterDelay: <Time in Seconds>)
0
Sujeet Shrivastav