J'ai un NSTimer
qui se déclenche avec un intervalle de 3 secondes pour diminuer une valeur. Lorsque je fais une action qui augmente cette valeur, je veux redémarrer la minuterie pour compter 3 secondes à partir de ce point. Par exemple, si j'augmente la valeur et que la minuterie se déclenche dans 1 seconde, je veux changer cela et déclencher la minuterie en 3 secondes à la place. Puis-je invalider le minuteur et le créer à nouveau? Ou puis-je le faire avec setFireDate:
, en utilisant la date actuelle et en ajoutant un intervalle de 3 secondes?Réinitialiser le temps de tir d'un NSTimer à partir de maintenant au lieu du dernier tir
Répondre
Oui, vous pouvez l'invalider. Et créez-le à nouveau.
Vous pouvez également utiliser:
- (void) myTimedTask {
// other stuff this task needs to do
// change the variable varyingDelay to be 1s or 3s or... This can be an instance variable or global that is changed by other parts of your app
// weStillWantTimer is also a similar variable that your app uses to stop this recurring task
if (weStillWantTimer)
[self performSelector:@selector(myTimedTask:) withObject:gameColor afterDelay:varyingDelay];
}
Vous appelez myTimedTask pour démarrer la tâche récurrente. Une fois qu'il est démarré, vous pouvez changer le délai avec varyDelay ou l'arrêter avec weStillWantTimer.
Invalide la minuterie et recrée-la. Cependant, assurez-vous que vous n'invalidez pas et relâchez la minuterie sauf si vous en êtes sûr car la boucle d'exécution conserve les minuteurs jusqu'à ce qu'ils soient invalidés, puis les libère elle-même. À mon avis, mixer -performSelector code avec le code timer mène à l'exécution multiple des méthodes cibles, donc je resterais loin de ça.
Oui, invalider et recréer la minuterie fonctionnera. C'est essentiellement ce que vous voulez faire si vous n'augmentez pas votre valeur: réinitialisez et recommencez.
Les setFireDate:
docs mentionnent que le changement de la date d'incendie est relativement coûteux, ce qui suggère qu'il pourrait être préférable de détruire et de recréer la minuterie à moins que vous faites si beaucoup. Par souci d'argumentation, cependant, j'ai attisé cette catégorie il y a un petit moment. Je préfère cela parce qu'il encapsule le comportement d'ajustement de la date; la minuterie elle-même le gère, plutôt que son propriétaire/contrôleur. Je n'ai pas de données sur la performance à ce sujet, cependant.
@implementation NSTimer (WSSAdjustingFireDate)
- (void)WSSFireAdjustingFireDate
{
[self fire];
[self WSSSkipNextFireAdjustingFireDate];
}
- (void)WSSSkipNextFireAdjustingFireDate
{
CFRunLoopTimerRef cfSelf = (__bridge CFRunLoopTimerRef)self;
CFTimeInterval delay = CFRunLoopTimerGetInterval(cfSelf);
CFRunLoopTimerSetNextFireDate(cfSelf, CFAbsoluteTimeGetCurrent() + delay);
}
@end
Je l'ai utilisé les fonctions de base de la Fondation juste pour éviter de créer un NSDate
. Optimisation prématurée? S'il te plaît, passe le sel.
J'ai fait un peu de test, et il s'avère que la réinitialisation du fireDate est environ quatre fois plus rapide que l'invalidation et la recréation du timer. Tout d'abord, je crée une minuterie qui appelle la méthode DoNothing:
if (!testTimer) {
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(doNothing:)
userInfo:nil
repeats:NO];
testTimer = timer;
}
Voici le code de test:
- (void) testInvalidatingTimer {
for (int n = 0; n < 10000; n++) {
[testTimer invalidate];
testTimer = nil;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(doNothing:)
userInfo:nil
repeats:NO];
testTimer = timer;
}
}
- (void) testResettingTimer {
for (int n = 0; n < 10000; n++) {
if ([testTimer isValid]) {
testTimer.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
}
}
}
Course à un iPad Air cède 0.198173 s pour invalidatingTimer et 0.044207 s pour resettingTimer. Si la performance est votre cible, je recommande de réinitialiser le fireDate. C'est aussi un peu moins d'effort de codage.
- 1. SqlConnection.SqlInfoMessageEvent pas de tir
- 2. WPF DataTrigger pas de tir au moment prévu
- 3. C# createuser wizard OnDeactivate pas de tir
- 4. jQuery gestionnaires de clics multiples ... comment assurer l'ordre de tir?
- 5. Ajax ConfimButtonExtender tir avant le code javascript OnClientClick
- 6. événement Initialized de WPF UserControl pas de tir
- 7. données chargées jQuery pas de tir modal comme il devrait
- 8. NStimer à partir de NSThread
- 9. C# BackgroundWorker Anomaly événement DoWork pas de tir
- 10. événement ImageButton pas de tir à l'intérieur de mise à jour panneau
- 11. Contrôle des séquences vidéo à partir de la ligne de temps principale au lieu d'utiliser leurs lignes de temps individuelles?
- 12. JSF commandeLink action tir avant la mise à jour des valeurs de modèle
- 13. ASP.NET personnalisé validateur côté client et serveur de validation de côté pas de tir
- 14. AutoCad événement EndPlot tir trop tôt (C#, API)
- 15. GMap - événement onrightclick pas de tir si le curseur non sur le dessus d'un marqueur
- 16. Eviter la double-cliquez sur la double tir d'une commande
- 17. comment réinitialiser le temps de DateTimePicker en C#
- 18. Mémoire fuite UIWebView lors du chargement à partir du fichier au lieu de l'URL?
- 19. Génération des migrations à partir des mises à jour du schéma Rails, au lieu de l'inverse
- 20. PHP - pop premier élément de tableau au lieu de dernier (array_pop reveresed)?
- 21. C# .Net Obtenir le dernier jour du mois précédent à partir de la date du jour
- 22. événement côté serveur de LinkButton pas de tir quand il est désactivé = true, et à l'intérieur d'un UpdatePanel, dans IE8
- 23. Activer la consignation des fichiers pour log4net à partir du code au lieu de la configuration
- 24. Débordement à gauche au lieu de droite
- 25. Héritage au lieu de typedef
- 26. Utilisation de NSTimer pour obtenir des timings précis
- 27. sorties php au lieu de -
- 28. Obtenez le temps total et le temps joué à partir du composant Flash Video?
- 29. Quel est le meilleur moyen de renvoyer un seul objet au lieu d'un tableau à partir de la sélection jQuery?
- 30. ValidateUser au lieu de LogonUser?
Enfin j'utilise setFireWithDate, quand j'augmente la valeur, j'envoie aussi un message au timer avec la date du jour plus trois secondes. Cela fonctionne ^^ Merci beaucoup. – emenegro