带有NSTimers的NSMutableDictionary

时间:2013-03-26 05:16:16

标签: objective-c nstimer nsmutabledictionary

我的CoreData中有几个食谱。每个食谱都有 prepHour prepMin 属性。我想通过点击按钮启动计时器启动倒数计时器。但是可以有几个定时器(例如每个配方)必须同时工作

我选择了这种方式(可能是错的):

  1. 对于计时器,我使用了单身计时器
  2. 点击我的启动计时器,我使用参数调用方法(name,prepHour,prepMin)
  3. 我的 startTimer 方法会创建计时器并将其置于NSMutableDictionary

  4. 通话方式:

    [[Timers sharedTimers] startTimer:self.recipe.name startTimer:self.recipe.prepHour startTimer:self.recipe.prepMin];
    

    在Timers中单身:

    - (void)startTimer:(NSString *)timerName  startTimer:(NSNumber *)hVal startTimer:(NSNumber *)mVal
    {
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(tick:) userInfo:nil repeats:YES];
        if ([timer isValid]) {
            NSArray *array = [NSArray arrayWithObjects: timer, hVal, mVal, nil];
            if (_timerDict == NULL) {
                _timerDict = [[NSMutableDictionary alloc] init];
            }
            [_timerDict setObject:array forKey:timerName];
            NSLog(@"%@", _timerDict);
        }
    }
    
    - (void)stopTimer:(NSString *)timerName
    {
        NSArray *array = [_timerDict objectForKey:timerName];
        NSTimer *timer = [array objectAtIndex:0];
        if ([timer isValid]) {
            [timer invalidate];
            [_timerDict removeObjectForKey:timerName];
        }
    }
    
    - (void)tick:(NSString *)timerName
    {
        NSArray *array = [_timerDict objectForKey:timerName];
        //NSTimer *timer = [array objectAtIndex:0];
        NSInteger hVal = [[array objectAtIndex:1] integerValue];
        NSInteger mVal = [[array objectAtIndex:2] integerValue];
        NSInteger sVal = 0;
    

    我应该如何为每个计时器使用 tick 方法?我希望每个计时器都使用自己的参数(timer,prepHour,prepMin)调用此方法

2 个答案:

答案 0 :(得分:2)

这可能是一个品味问题,但我不使用计时器来记住一个到期时间,我用它们以一定频率脉冲。对于你的应用程序,我会使用最低公分母频率的一个计时器,如一秒钟。我有一个单一的计时器,而不是单身人士,应用程序代表可以使其无效并重新启动。

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(tick:) userInfo:nil repeats:YES];

然后将每个过期作为每个食谱的一个属性。例如:

- (IBAction)pressedStartButtonForRecipeA:(id)sender {

    // this is a NSDate * property
    self.recipeADone = [NSDate dateWithTimeIntervalSinceNow:90*60];  // ninety minutes
}

- (void)tick:(NSTimer *)timer {

    NSDate *now = [NSDate date];
    NSTimeInterval secondsUntilAIsDone = [self.recipeADone timeIntervalSinceDate:now];

    if (secondsUntilAIsDone <= 0.0) {
        // update UI to say that A is done
    } else {
        // update UI to reduce countdown
    }

    // and so on for all recipes
}

答案 1 :(得分:1)

这听起来像是对单身人士的不良使用。如果你想采用这种设计,我会......每个计时器一个计时器。或者,你可以有一个计时器,只需计算每个计时器启动时的偏移量。 (哪种方法有意义取决于你的特定应用。我通常会选择第二种,但YMMV。)

此外,计时器不会将NSString传递给它们的回调;他们自己过去了。要允许回调从计时器获取一些信息,您可以将信息设置为计时器的userInfo字典。