Comment créer un retard dans l'Swift?
Je veux mettre en pause mon application à un certain point. En d'autres termes, je veux que mon application pour exécuter le code, mais à un certain point, une pause de 4 secondes, puis continuer avec le reste du code. Comment puis-je faire cela?
Je suis en utilisant Swift.
Vous devez vous connecter pour publier un commentaire.
Au lieu de sommeil, qui permet de verrouiller votre programme si elle est appelée à partir de la thread de l'INTERFACE utilisateur, pensez à utiliser
NSTimer
ou une expédition de la minuterie.Mais, si vous avez vraiment besoin d'un retard dans le thread actuel:
Il utilise le
sommeil
fonction d'UNIX.À l'aide d'un
dispatch_after
bloc est dans la plupart des cas, mieux que d'utilisersleep(time)
que le thread sur lequel le sommeil est effectuée est bloqué en faisant d'autres travaux. lors de l'utilisation dedispatch_after
le thread qui a travaillé sur de ne pas se bloquer, donc il peut faire d'autres travaux dans le temps.Si vous travaillez sur le thread principal de votre application, à l'aide de
sleep(time)
est mauvais pour l'expérience utilisateur de votre application que l'INTERFACE utilisateur ne répond pas pendant ce temps.Expédition après les horaires de l'exécution d'un bloc de code au lieu de geler le thread:
Swift ≥ 3.0
Swift < 3.0
.now() + .seconds(4)
donne une erreur:expression type is ambiguous without more context
.now() + .seconds(5)
il est tout simplement.now() + 5
+ .seconds(5)
+ DispatchTimeInterval.seconds(4)
.now() + 5
au lieu de.now() + .seconds(5)
. J'obtiens cette erreur sinon:gives error: expression type is ambiguous without more context
Comparaison entre les différentes approches en swift 3.0
1. Sommeil
Cette méthode ne permet pas d'avoir un retour d'appel. Mettre les codes directement après cette ligne pour être exécuté dans les 4 secondes. Il va cesser d'utilisateur à partir de l'itération avec des éléments de l'INTERFACE utilisateur, comme le bouton test jusqu'à ce que le temps est passé. Bien que le bouton est une sorte de gelée quand le sommeil se met en marche, d'autres éléments comme l'indicateur d'activité est toujours en rotation, sans le figer. Vous ne pouvez pas déclencher à nouveau cette action pendant le sommeil.
2. D'expédition, d'Effectuer et de la Minuterie
Ces trois méthodes fonctionnent de la même façon, ils sont tous en cours d'exécution sur le thread d'arrière-plan avec des blagues, juste avec une syntaxe différente et des caractéristiques légèrement différentes.
De l'expédition est couramment utilisé pour exécuter quelque chose sur le thread d'arrière-plan. Il a la fonction de rappel dans le cadre de l'appel de la fonction
Effectuer est en fait une simplification de la minuterie. Il met en place un timer avec du retard, puis déclencher la fonction par sélecteur.
Et enfin, la minuterie fournit également la capacité de répéter le rappel, qui n'est pas utile dans ce cas
Pour chacun de ces trois méthode, lorsque vous cliquez sur le bouton pour déclencher l'INTERFACE utilisateur ne gèlera pas, et vous êtes autorisé à cliquer dessus à nouveau. Si vous cliquez sur le bouton de nouveau, un autre chronomètre est mis en place et le rappel sera déclenché deux fois.
En conclusion
Aucun des quatre méthode fonctionne assez bon juste par eux-mêmes.
sleep
va désactiver l'interaction de l'utilisateur, de sorte que l'écran "gèle"(pas fait) et les résultats de la qualité de l'expérience utilisateur. Les trois autres méthodes seront pas de gel de l'écran, mais vous pouvez les déclencher plusieurs fois, et la plupart du temps, vous voulez attendre jusqu'à ce que vous obtenir le retour d'appel avant de permettre à un utilisateur d'appeler à nouveau.Donc une meilleure conception sera en utilisant une des trois méthodes asynchrones avec écran de blocage. Lorsque l'utilisateur clique sur le bouton, de couvrir la totalité de l'écran avec certains translucide vue avec une filature de l'indicateur d'activité sur le dessus, en disant à l'utilisateur que le bouton est en cours de traitement. Ensuite, retirer de la vue et de l'indicateur dans la fonction de rappel, en disant à l'utilisateur que l'action est correctement géré, etc.
@objc
devant de la fonction de rappel pour leperform(...)
option. Comme:@objc func callback() {
Je suis d'accord avec Palle que l'utilisation de
dispatch_after
est un bon choix ici. Mais vous n'aimez probablement pas le PGCD des appels comme ils sont assez ennuyeux à écrire. Au lieu de cela, vous pouvez ajouter ce pratique helper:Maintenant, il vous suffit de retarder votre code sur un thread d'arrière-plan comme ceci:
Retarder le code sur le thread principal est encore plus simple:
Si vous préférez un Cadre que aussi plus de fonctionnalités à portée de main alors commander HandySwift. Vous pouvez l'ajouter à votre projet via Carthage ou Accio ensuite l'utiliser exactement comme dans les exemples ci-dessus:
DispatchTime
n'était pas disponible en Swift 2. Il a étélet dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
avant.Vous pouvez également le faire avec Swift 3.
Exécuter la fonction après le délai comme si.
NSTimer
La réponse par @nneonneo a suggéré d'utiliser
NSTimer
mais n'a pas pu montrer comment le faire. C'est la syntaxe de base:Ici est un projet très simple pour montrer comment il pourrait l'être. Quand un bouton est pressé, il commence une minuterie qui va appeler une fonction après un retard d'une demi-seconde.
À l'aide de
dispatch_time
(comme dans Palle réponse) est une autre option valable. Cependant, il est dur pour annuler. AvecNSTimer
, pour annuler un retard de l'événement avant qu'il arrive, tout ce que vous devez faire est d'appelerÀ l'aide de
sleep
n'est pas recommandé, surtout sur le thread principal, puisqu'il s'arrête tout le travail effectué sur le fil.Voir ici pour mon fuller réponse.
Dans Swift Xcode 4.2 et 10.1
Vous avez tout à fait le 4 façons de retard. De tous les option 1 est préférable d'appeler ou d'exécuter une fonction après un certain temps. De tous les sleep() est moins le cas en cours d'utilisation.
L'Option 1.
L'Option 2.
Option 3.
Option 4.
Essayez la suite de la mise en œuvre de Swift 3.0
Utilisation
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {/*Do stuff*/}
Est probablement plus correct ✌️Si vous avez besoin de définir un délai de moins d'une seconde, il n'est pas nécessaire de définir le .secondes paramètre. J'espère que c'est utile à quelqu'un.
Vous pouvez créer une extension pour utiliser la fonction de délai facilement (Syntaxe: Swift 4.2+)
Comment utiliser dans UIViewController
Pour créer un simple retard de temps, vous pouvez importer Darwin et ensuite utiliser le sommeil(en secondes) pour faire de ce retard. Qui ne prend en secondes, bien que, pour des mesures plus précises, vous pouvez importer Darwin et l'utilisation usleep(millionièmes de seconde) pour une mesure précise. Pour tester cela, j'ai écrit:
Qui imprime, puis attend pendant 1 sec et de tirages, puis attend de 0,4 sec puis imprime. Tout a fonctionné comme prévu.
Si votre code est déjà en cours d'exécution dans un thread d'arrière-plan, mettre en pause le thread à l'aide de cette méthode de Fondation:
Thread.sleep(forTimeInterval:)
Par exemple:
(Voir les autres réponses pour des suggestions lorsque votre code est en cours d'exécution sur le thread principal.)
c'est le plus simple