web-dev-qa-db-fra.com

NSTimer ne déclenche pas le sélecteur

Dans ios5.0 avec ARC, dans mon rootviewcontroller j'appelle une méthode dans un objet de gestionnaire de sécurité qui est détenu par le délégué de l'application. Dans cette méthode, je configure le minuteur comme ci-dessous

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
                                       selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

Cependant, cela ne déclenche jamais le sélecteur ie. updateModel: n'est jamais appelé. Qu'est-ce qui ne va pas? Existe-t-il un autre moyen plus efficace de le faire sans utiliser NStimer?

30
inforeqd

Vous semblez être un peu mélangé avec votre variable timer.

Vous initialisez une nouvelle minuterie mais vous ne l'utilisez pas réellement. Voulez-vous utiliser la minuterie que vous avez initialisée ou voulez-vous ApplicationDelegate.timer?

Voici les deux solutions possibles.

Option 1 (en supposant que vous avez une instance de classe intitulée ApplicationDelegate et qu'elle possède une propriété timer):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];

Deuxième option:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
13
sosborn

Peut également être un problème de thread:

si

[NSThread isMainThread]

est faux, puis lancez le minuteur comme ceci:

dispatch_async(dispatch_get_main_queue(), ^{
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
    })
116
tmanthey

J'attrape le même problème et je déclenche la minuterie dans la file d'attente principale pour le résoudre:

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
         [self loopUpUpdateStart];
}];

-(void)loopUpUpdateStart{
    dispatch_async(dispatch_get_main_queue(), ^{

        _loopTimerForUpRevision = 
          NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev
                                          target: self
                                        selector: @selector(myCoolMethod)
                                        userInfo: nil
                                         repeats: YES];
        TRACE(@"Start Up updates");
    });
}
8
WINSergey

Cette ligne a plusieurs problèmes:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

Premièrement, cela ne devrait pas du tout être requis. -scheduledTimerWithTimeInterval:... ajoute déjà la minuterie au runloop. Vous n'avez pas besoin de l'ajouter à nouveau.

Deuxièmement, la variable locale timer n'est pas liée à la propriété ApplicationDelegate.timer (qui est vraisemblablement nil à ce stade).

Si vous parlez tellement au délégué de l'application que vous avez créé quelque chose appelé ApplicationDelegate (un global? Une macro?), Vous lui parlez trop. Le délégué d'application est le délégué de l'application; il assiste le démarrage et l'arrêt de l'application et la réponse aux événements système. Le délégué d'application n'est pas un endroit pour stocker des variables globales. Une minuterie n'est certainement pas le genre de chose que vous chercheriez dans un autre objet en tout cas.

7
Rob Napier