Existe-t-il un moyen d'appeler un bloc avec un paramètre primitif après un délai, comme en utilisant performSelector:withObject:afterDelay:
mais avec un argument comme int
/ double
/ float
?
734
Existe-t-il un moyen d'appeler un bloc avec un paramètre primitif après un délai, comme en utilisant performSelector:withObject:afterDelay:
mais avec un argument comme int
/ double
/ float
?
Réponses:
Je pense que vous cherchez
dispatch_after()
. Il nécessite que votre bloc n'accepte aucun paramètre, mais vous pouvez simplement laisser le bloc capturer ces variables à partir de votre portée locale à la place.Plus: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
la source
dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC)
extrait est méchant. N'y a-t-il pas un moyen plus propre pour cela?dispatch_get_current_queue()
renvoie toujours la file d'attente à partir de laquelle le code est exécuté. Ainsi, lorsque ce code est exécuté à partir du thread principal, le bloc sera également exécuté sur le thread principal.dispatch_get_current_queue()
est désormais obsolèteVous pouvez utiliser
dispatch_after
pour appeler un bloc ultérieurement. Dans Xcode, commencez à taperdispatch_after
et appuyez surEnter
pour compléter automatiquement les éléments suivants:Voici un exemple avec deux flottants comme «arguments». Vous n'avez pas à vous fier à n'importe quel type de macro, et l'intention du code est assez claire:
Swift 3, Swift 4
Swift 2
Objectif c
la source
NSEC_PER_SEC * 0.5
fonctionnerait de la même manière queNSEC_PER_MSEC * 500
. Bien que vous ayez raison de noter qu'ildispatch_time
attend un entier 64 bits, la valeur attendue est en nanosecondes.NSEC_PER_SEC
est défini comme1000000000ull
, et multiplier cela avec une constante à0.5
virgule flottante effectuerait implicitement une arithmétique à virgule flottante, produisant500000000.0
, avant qu'elle ne soit explicitement convertie en un entier 64 bits. Il est donc parfaitement acceptable d'utiliser une fraction deNSEC_PER_SEC
.Que diriez-vous d'utiliser la bibliothèque d'extraits de code Xcode intégrée?
Mise à jour pour Swift:
Beaucoup de votes positifs m'ont inspiré pour mettre à jour cette réponse.
La bibliothèque d'extraits de code Xcode intégrée a
dispatch_after
pour seuleobjective-c
langue. Les utilisateurs peuvent également créer leur propre extrait de code personnalisé pourSwift
.Écrivez ceci dans Xcode.
Faites glisser ce code et déposez-le dans la zone de bibliothèque d'extraits de code.
En bas de la liste d'extraits de code, il y aura une nouvelle entité nommée
My Code Snippet
. Modifiez ceci pour un titre. Pour des suggestions en tapant le Xcode, remplissez leCompletion Shortcut
.Pour plus d'informations, voir Création d'un SnapCodeCustomCode .
Mettre à jour Swift 3
Faites glisser ce code et déposez-le dans la zone de bibliothèque d'extraits de code.
la source
En développant la réponse de Jaime Cham, j'ai créé une catégorie NSObject + Blocks comme ci-dessous. Je pensais que ces méthodes correspondaient mieux aux
performSelector:
méthodes NSObject existantesNSObject + Blocks.h
NSObject + Blocks.m
et utiliser comme ça:
la source
delay
devrait être deNSTimeInterval
(qui est undouble
).#import <UIKit/UIKit.h>
n'est pas nécessaire. Et, je ne vois pas pourquoi cela- (void)performBlock:(void (^)())block;
pourrait être utile, donc peut être supprimé de l'en-tête.Peut-être plus simple que de passer par GCD, dans une classe quelque part (par exemple "Util"), ou une catégorie sur un objet:
Donc à utiliser:
la source
Pour Swift, j'ai créé une fonction globale, rien de spécial, en utilisant la
dispatch_after
méthode. J'aime plus cela car il est lisible et facile à utiliser:Que vous pouvez utiliser comme suit:
la source
after
. Ensuite, vous pouvez écrire:after(2.0){ print("do somthing") }
Voici mes 2 cents = 5 méthodes;)
J'aime encapsuler ces détails et demander à AppCode de me dire comment terminer mes phrases.
la source
PerformSelector: WithObject prend toujours un objet, donc pour passer des arguments comme int / double / float etc ..... Vous pouvez utiliser quelque chose comme ça.
// NSNumber est un objet ..
De la même manière, vous pouvez utiliser [NSNumber numberWithInt:] etc .... et dans la méthode de réception, vous pouvez convertir le nombre dans votre format en tant que [nombre entier] ou [numéro double].
la source
La fonction dispatch_after distribue un objet bloc dans une file d'attente de répartition après un laps de temps donné. Utilisez le code ci-dessous pour effectuer certaines tâches liées à l'interface utilisateur après 2,0 secondes.
Dans swift 3.0:
la source
mainQueue,
au lieu demainQueue)
Voici la méthode Swift 3 pour mettre en file d'attente le travail après un délai.
la source
Voici une aide pratique pour éviter de faire des appels GCD ennuyeux encore et encore:
Maintenant, vous retardez simplement votre code sur le fil principal comme ceci:
Si vous souhaitez retarder votre code sur un thread différent :
Si vous préférez un Framework qui possède également des fonctionnalités plus pratiques, passez à HandySwift . Vous pouvez l'ajouter à votre projet via Carthage puis l'utiliser exactement comme dans les exemples ci-dessus:
la source
Il y en a une belle dans le framework BlocksKit.
BlocksKit
(et la classe)
BBlocksKit.m
la source
Dans swift 3, nous pouvons simplement utiliser la fonction DispatchQueue.main.asyncAfter pour déclencher toute fonction ou action après le délai de 'n' secondes. Ici, dans le code, nous avons défini le délai après 1 seconde. Vous appelez n'importe quelle fonction à l'intérieur du corps de cette fonction qui se déclenchera après le délai de 1 seconde.
la source
Xcode 10.2 et Swift 5 et supérieur
la source
Vous pouvez soit encapsuler l'argument dans votre propre classe, soit encapsuler l'appel de méthode dans une méthode qui n'a pas besoin d'être passée dans le type primitif. Appelez ensuite cette méthode après votre délai, et dans cette méthode, effectuez le sélecteur que vous souhaitez effectuer.
la source
Voici comment déclencher un blocage après un retard dans Swift:
Il est inclus en tant que fonction standard dans mon référentiel .
la source
Swift 3 et Xcode 8.3.2
Ce code vous aidera, j'ajoute aussi une explication
la source
Je crois que l'auteur ne demande pas comment attendre un temps fractionnaire (retard), mais plutôt comment passer un scalaire comme argument du sélecteur (withObject :) et le moyen le plus rapide dans l'objectif moderne C est:
votre sélecteur doit changer son paramètre en NSNumber et récupérer la valeur en utilisant un sélecteur comme floatValue ou doubleValue
la source