2010-07-01 6 views
2

J'ai une application iPhone avec un NSTimer appelé pressTimer qui s'éteint chaque fois que quelqu'un touche ce bouton. Le problème est qu'ils touchent beaucoup le bouton, et je veux que la minuterie s'arrête quand ils lèvent leur doigt. J'ai donc déclaré pressTimer dans mon fichier .h et l'ai synthétisé en .m puis assigné et lancé sur l'action TouchDown que j'ai créée. J'utilise le code [pressTimer invalidate] sur mon action TouchUpInside qui devrait annuler le timer, puisqu'il s'agit d'une variable globale. Il semble annuler le minuteur, mais quand je vais déclencher la minuterie, le programme se fige complètement, même si je n'ai pas d'erreur de code ou d'avertissement. Je suis un noob, alors s'il vous plaît ne soyez pas trop bruts: 0Comment invalider correctement un NSTimer

Mise à jour: Logs de la console- Merci les gars!

continue 
2010-07-01 16:39:30.981 Clickkr[1573:307] -[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40 
2010-07-01 16:39:30.999 Clickkr[1573:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x309a5fd3 __exceptionPreprocess + 114 
    1 libobjc.A.dylib      0x318b58a5 objc_exception_throw + 24 
    2 CoreFoundation      0x309a9a77 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102 
    3 CoreFoundation      0x309a8f15 ___forwarding___ + 508 
    4 CoreFoundation      0x3093b680 _CF_forwarding_prep_0 + 48 
    5 Clickkr        0x00002b23 -[MyViewController addOne:] + 42 
    6 CoreFoundation      0x309307ad -[NSObject(NSObject) performSelector:withObject:withObject:] + 24 
    7 UIKit        0x31e1f829 -[UIApplication sendAction:to:from:forEvent:] + 84 
    8 UIKit        0x31e1f7c9 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32 
    9 UIKit        0x31e1f79b -[UIControl sendAction:to:forEvent:] + 38 
    10 UIKit        0x31e1f4ed -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356 
    11 UIKit        0x31e1fb3b -[UIControl touchesEnded:withEvent:] + 342 
    12 UIKit        0x31e1e4ed -[UIWindow _sendTouchesForEvent:] + 368 
    13 UIKit        0x31e1de67 -[UIWindow sendEvent:] + 262 
    14 UIKit        0x31e19b5b -[UIApplication sendEvent:] + 298 
    15 UIKit        0x31e19507 _UIApplicationHandleEvent + 5022 
    16 GraphicsServices     0x30a8c147 PurpleEventCallback + 666 
    17 CoreFoundation      0x3097baab __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26 
    18 CoreFoundation      0x3097d84f __CFRunLoopDoSource1 + 166 
    19 CoreFoundation      0x3097e62d __CFRunLoopRun + 520 
    20 CoreFoundation      0x309278eb CFRunLoopRunSpecific + 230 
    21 CoreFoundation      0x309277f3 CFRunLoopRunInMode + 58 
    22 GraphicsServices     0x30a8b6ef GSEventRunModal + 114 
    23 GraphicsServices     0x30a8b79b GSEventRun + 62 
    24 UIKit        0x31dc32a7 -[UIApplication _run] + 402 
    25 UIKit        0x31dc1e17 UIApplicationMain + 670 
    26 Clickkr        0x00002333 main + 70 
    27 Clickkr        0x000022e8 start + 40 
) 
terminate called after throwing an instance of 'NSException' 
Program received signal: “SIGABRT”. 

Répondre

7

C'est la façon dont j'invalident minuteries:

[timer invalidate]; 
timer = nil; 

Le problème que vous rencontrez sans doute est qu'une fois que votre minuterie est invalidée, il est retiré de la boucle d'exécution et quand quelqu'un veut un accès il, votre programme se bloque. Après l'avoir invalidé, faites en sorte qu'il soit nul. De cette façon, si quelqu'un veut envoyer un message ou faire quoi que ce soit, il l'enverra à zéro.

+0

Merci. Si je fais cela, mon minuteur ne peut pas être déclenché à nouveau, n'est-ce pas? Ce que j'essaie de faire, c'est sentir si un utilisateur appuie sur le bouton pendant 3 secondes il ouvre un champ de texte pour éditer quelque chose. Le bouton a aussi un autre but, si vous ne tapez que brièvement, alors je veux m'assurer que la minuterie continuera à se déclencher chaque fois que vous appuyez sur le bouton, pour vérifier. – SeniorShizzle

+0

Juste instancier un nouveau temporisateur en cas de besoin. –

+0

Sucré. Je l'ai fait et je n'ai aucun problème avec la réinitialisation de la minuterie, mais elle se fige quand la minuterie déclenche le sélecteur. Je peux poster le journal de la console si cela peut aider. – SeniorShizzle

0

Le journal indique quelque chose de mal avec addOne ... quel est le rapport avec la minuterie?

+0

addOne est un IBAction et les deux premières lignes sont [pressTimer invalidate] et pressTimer = nil. C'est le seul moyen de les connecter. Je ne reçois aucune erreur ou avertissement, soit – SeniorShizzle

0

Les gars, je l'ai compris après un peu de déconner avec elle. La méthode d'Anauel pour arrêter les minuteurs fonctionnait très bien, mais pour une raison quelconque, mon nom de méthode était en conflit avec le sélecteur de la minuterie, alors j'ai changé les deux. J'ai aussi ajouté le code d'Anauel à la méthode que j'ai utilisée comme sélecteur. Merci!

1
@interface 
    NSTimer * yourTimer; 

@property (nonatomic, retain) yourTimer; 
@synthesize yourTimer; 

@implement  
    self.yourTimer = [NSTimer scheduledTimerWithTimeInterval:5 
                target:self 
                selector:@selector(yourSelector) 
                userInfo:nil 
                repeats:NO]; 

    //Wherever you want to stop the timer, 
    [yourTimer invalidate]; 
    self.yourTimer = nil; 
0

Je mieux ajouter un chèque de l'indicateur de validité et de l'objet timer instance

-(void) clearKeepAliveTimer { 
    if(keepAliveTimer && [keepAliveTimer isValid]) { 
     [keepAliveTimer invalidate]; 
     keepAliveTimer = nil; 
    } }