J'essaie de transmettre des données via userInfo pour un appel NSTimer. Quelle est la meilleure façon de procéder? J'essaie d'utiliser un NSDictionary, c'est assez simple quand j'ai des objets Objective-C, mais qu'en est-il des autres données? Je veux faire quelque chose comme ça, qui ne fonctionne pas tel quel:
- (void)play:(SystemSoundID)sound target:(id)target callbackSelector:(SEL)selector
{
NSLog(@"pause iPod");
[iPodController pause];
theSound = sound;
NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
[cb setObject:(id)&sound forKey:@"sound"];
[cb setObject:target forKey:@"target"];
[cb setObject:(id)&selector forKey:@"selector"];
[NSTimer scheduledTimerWithTimeInterval:0
target:self
selector:@selector(notifyPause1:)
userInfo:(id)cb
repeats:NO];
}
Vous devez intégrer correctement les informations dans le dictionnaire:
- (void) play:(SystemSoundID)sound target:(id)target callbackSelector:(SEL)selector
{
NSLog(@"pause iPod");
[iPodController pause];
theSound = sound;
NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
[cb setObject:[NSNumber numberWithInt:sound] forKey:@"sound"];
[cb setObject:target forKey:@"target"];
[cb setObject:NSStringFromSelector(selector) forKey:@"selector"];
[NSTimer scheduledTimerWithTimeInterval:0
target:self
selector:@selector(notifyPause1:)
userInfo:cb
repeats:NO];
[cb release];
}
Dans notifyPause1:
, vous récupérez tout:
- (void)notifyPause1:(NSTimer *)timer {
NSDictionary *dict = [timer userInfo];
SystemSoundID sound = [[dict objectForKey:@"sound"] intValue];
id target = [dict objectForKey:@"target"];
SEL selector = NSSelectorFromString([dict objectForKey:@"selector"]);
// Do whatever...
}
Comme le minuteur est un minuteur qui se répète, vous n’avez plus besoin du dictionnaire, vous pouvez donc le relâcher.
Votre appel est bon, mais vous n’avez pas à lancer le dictionnaire pour id. Vous pouvez récupérer les informations utilisateur avec la ligne suivante dans votre méthode notifyPause1:
- (void)notifyPause1:(NSTimer *)timer {
NSDictionary *dict = [timer userInfo];
}
Vous pouvez demander la minuterie dans la méthode donnée au sélecteur,
Ensuite, vous pouvez extraire useInfo de ce minuteur ( timer.userInfo ):
- (void)settingTimer
{
[NSTimer scheduledTimerWithTimeInterval:kYourTimeInterval
target:self
selector:@selector(timerFired:)
userInfo:yourObject
repeats:NO];
}
- (void)timerFired:(NSTimer*)theTimer
{
id yourObject = theTimer.userInfo;
//your code here
}
La méthode de Laurent Etiemble fonctionne bien pour faire bon usage des méthodes de minuterie dans les sous-classes de UIViewcontroller qui peuvent être facilement utilisées dans plusieurs contrôleurs de vue.
Vous trouverez ci-dessous un moyen d'écrire un affichage de score générique qui peut être utilisé à plusieurs reprises dans la même application en passant la vue à travers NSTimer userInfo.
.h (sous-classe de UIViewcontroller)
- (NSTimeInterval) timeSet;
- (void) timeRun: (UISegmentedControl*)scoreDisplay;
- (void) timeWrite: (NSTimer *)timer;
.m
- (NSTimeInterval) timeSet {
return [self.startTime timeIntervalSinceNow];
}
- (void) timeWrite: (NSTimer *)timer
{
NSDictionary *dict = [timer userInfo];
UISegmentedControl *scoreDisplay = [dict objectForKey:@"scoreDisplay"];
int myint = round([self timeSet]);
NSString* buttonWrite = [[[NSString stringWithFormat:@"Score: %d", self.answered] stringByAppendingString:[NSString stringWithFormat:@" Errors: %d", self.errors]] stringByAppendingString:[NSString stringWithFormat:@" Time: %d", (myint*-1)]];
[scoreDisplay setTitle:buttonWrite forSegmentAtIndex:0];
}
- (void) timeRun: (UISegmentedControl*)scoreDisplay
{
self.startTime = [NSDate date];
NSMutableDictionary *cb = [[NSMutableDictionary alloc] init];
[cb setObject:scoreDisplay forKey:@"scoreDisplay"];
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(timeWrite:)
userInfo:cb
repeats:YES];
}
Dans le contrôleur de vue
.m
- (void)viewDidLoad
{
[super viewDidLoad];
//load ScoreDisplay
[self timeRun:self.scoreDisplay];
}
sound
et selector
ne sont pas des objets Objective-C: sound
est un nombre non signé et selector
est un pointeur sur une structure C. Cela risquerait de provoquer un crash.
Vous voudrez utiliser NSValue pour conserver la valeur de selector
et NSNumber pour conserver la valeur de sound
. NSValue et NSNumber sont des objets et fonctionneront avec NSMutableDictionary.
Vous ne devez pas convertir vos objets en identifiant lors de l'attribution au dictionnaire. Tout objet pouvant être incorporé directement dans une NSDictionary
dérive déjà de NSObject
et est implicitement concordé en id. Enregistrez le nom du sélecteur sous la forme NSString
(à l'aide de NSStringFromSelector()
), puis convertissez-le en sélecteur à l'aide de NSSelectorFromString()
Claus