2010-02-07 6 views
6

J'ai utilisé un NSTimer avec succès, mais j'ai maintenant des problèmes avec. Indubitablement quelque chose de stupide. Appréciez un autre ensemble d'yeux. En exécutant le débogueur, je vois que applicationDidFinishLaunching est appelée, mais le déclencheur n'est jamais appelé.NStimer - qu'est-ce que je fais mal ici?

-(void) trigger:(NSTimer *) theTimer{ 
    NSLog(@"timer fired"); 
} 

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

    nst = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(trigger) userInfo:nil repeats:YES]; 

    [window makeKeyAndVisible]; 
} 
+0

En plus de ce qui a été dit ci-dessous, vous devez conserver la minuterie si vous n'utilisez pas la récupération de place. –

+2

Si vous ajoutez le timer pour lancer la boucle, il n'y a pas besoin de le conserver, je pense que la boucle d'exécution le retient. – Jaanus

+0

Merci à tous pour avoir détecté l'erreur de signature de la méthode. L'autre chose qui m'a fait trébucher, c'est que j'avais utilisé schedTimerWithInterval, qui ne nécessite pas d'ajout manuel à une boucle d'exécution. Dans ce cas, j'avais oublié la partie scheduledTimer. – morgancodes

Répondre

13

Le sélecteur doit avoir la signature suivante:

- (void)timerFireMethod:(NSTimer*)theTimer 

si vous avez besoin

@selector(trigger:) 

--edit--

Peut-être que vous faites cela quelque part ailleurs, mais dans le code vous avez compris que vous ne démarrez pas réellement le minuteur. Vous devez l'ajouter à un NSRunLoop avant qu'il puisse déclencher des événements du tout.

[[NSRunLoop currentRunLoop] addTimer:nst forMode:NSDefaultRunLoopMode]; 

Si je lis les exemples correctement. J'ai seulement utilisé la méthode init qui l'ajoute automatiquement au NSRunLoop actuel. Vous devriez vraiment regarder les docs de développeur que quelqu'un a inclus dans les commentaires à mon poste.

+1

bleh trop lent encore, désolé noah :) – willcodejavaforfood

+0

+1 Voici la documentation pertinente: http://developer.apple.com/mac/library/documentation/cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html # // apple_ref/occ/clm/NSTimer/timerWithTimeInterval: target: sélecteur: userInfo: répète: –

+1

pour clarifier: -: fait partie du nom de la méthode. Infact: est un nom de méthode totalement valide pour une méthode avec un argument. –

1

Le sélecteur vous donnez la minuterie, trigger, indique qu'il doit appeler une méthode qui ne prend aucun paramètre. Modifiez votre méthode feu minuterie à

- (void)trigger 
{ 
     // look at me, I don't take any parameters 
     NSLog(@"timer fired"); 
} 

ou modifier votre appel initial à utiliser minuterie @selector(trigger:).

+1

Le rappel de minuterie doit avoir un argument, donc changer le nom de la méthode en "trigger" ne fonctionnera pas –

+2

@jib - Non ce n'est pas vrai. Le rappel de la minuterie fonctionne correctement sans l'argument NSTimer. Je fais ça tout le temps. –

2

Deux choses:

1) comme d'autres disent, la méthode doit avoir la signature suivante ..

-(void) trigger:(NSTimer *) theTimer; 

et vous faites la minuterie ainsi:

nst = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(trigger:) userInfo:nil repeats:YES]; 

2) seulement la création de la minuterie ne l'exécute pas. Comme the documentation says:

Vous devez ajouter la nouvelle minuterie à une boucle course , en utilisant addTimer: forMode :. Puis, après que les secondes se soient écoulées, le temporisateur se déclenche, invoquant l'invocation. (Si le timer est configuré pour répéter, il est inutile de rajouter ensuite la minuterie à la boucle d'exécution.)

Voici un morceau de code réel de fonctionnement que vous pouvez modéliser après. La création de la minuterie est la même que la vôtre, mais elle l'ajoute également au bon déroulement.

[[NSRunLoop currentRunLoop] addTimer: 
    [NSTimer timerWithTimeInterval:0.1 
          target:self 
          selector:@selector(someSelector:) 
          userInfo:nil 
          repeats:NO] 
           forMode:NSDefaultRunLoopMode]; 
+4

+1 c'est correct. Vous pouvez également utiliser les méthodes de commodité 'scheduledTimer ...' qui ajouteront le timer à la boucle d'exécution pour vous. –

0

Votre problème est dû au fait que timerWithTimeInterval:target:selector:userInfo:repeats: crée une minuterie, mais ne pas programme sur la boucle d'exécution, vous devez le faire vous-même.

Cependant, vous pouvez aussi bien utiliser cette méthode qui crée la minuterie horaires et sur la boucle d'exécution: scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

0

J'ai eu un problème lorsque la minuterie à partir de - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { pas thread principal.

dispatch_async(dispatch_get_main_queue(), ^{ 
[self startScheduledTimer]; 
}); 
Questions connexes