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?
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];
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];
})
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");
});
}
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.