0

以下のコードを使用して、SQLite データベースに格納されたデータから多数 (~5) の NSTimer インスタンスを作成しています。

-(void)setupNotificationTimer:(NSDictionary *)timerDetails{

    NSLog(@"TIMER REPEATS VALUE: %@", [timerDetails objectForKey:@"repeats"]);
    NSLog(@"INTERVAL: %f", [[timerDetails objectForKey:@"interval"] floatValue]);

    bool repeat = [[timerDetails objectForKey:@"repeats"] boolValue];
    if (repeat) {
        NSLog(@"Should Repeat");
    }
    else{
        NSLog(@"Should Not Repeat");
    }

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:[[timerDetails objectForKey:@"interval"] floatValue]
                                     target:self
                                   selector:@selector(fireTimer:)
                                   userInfo:timerDetails
                                    repeats:repeat];
    [timer fire];
    [timers addObject:timer]; //'timers' is a property of the AppDelegate
}

-(void)fireTimer:(NSTimer *)timer {
    NSLog(@"Timer Fired");
    NSMutableDictionary *dict = [timer userInfo];
    [[NSNotificationCenter defaultCenter] postNotificationName:[dict objectForKey:@"notificationName"] object:nil];
}

これらのタイマーを設定すると、アプリが初めてロードされたときにタイマーが正しく設定されますが、以下の NSLog 出力が示すように、明確に繰り返すように設定されているにもかかわらず繰り返されません。各タイマーは 1 回起動し、その後は継続しません。

2013-04-03 11:12:53.541 Test[2635:752b] TIMER REPEATS VALUE: 1
2013-04-03 11:12:53.542 Test[2635:752b] INTERVAL: 10.000000
2013-04-03 11:12:53.543 Test[2635:752b] Should Repeat
2013-04-03 11:12:53.544 Test[2635:752b] Timer Fired

アプリを閉じてから再度開くと、奇妙なことが起こり、タイマーが作成され、実際に繰り返し起動します。このアプリはユニバーサル iPhone および iPad アプリでもあり、iPhone でアプリを実行している場合にのみこの動作が発生するようです。私は本当にこれに困惑しており、どんな助けも大歓迎です。

編集

タイマーをキャンセルするコードを要求したとおり:

-(void)viewWillDisappear:(BOOL)animated{        
    NSArray *viewControllersSet = self.navigationController.viewControllers;
    if (viewControllersSet.count > 1 && [viewControllersSet objectAtIndex:viewControllersSet.count-2] == self) {
        // View is disappearing because a new view controller was pushed onto the stack
        NSLog(@"New view controller was pushed");
    } else if ([viewControllersSet indexOfObject:self] == NSNotFound) {
        // View is disappearing because it was popped from the stack
        NSLog(@"View controller was popped");
        for(int i = 0; i < [[appDelegate timers] count]; i ++){
            NSTimer *timer = [[appDelegate timers] objectAtIndex:i];
            [timer invalidate];
            timer = nil;
        }
        [[appDelegate timers] removeAllObjects];
    }
}
4

1 に答える 1

1

scheduleTimerWithTimeInterval で作成された後に NSTimer が起動しない場合、通常は、NSTimer が正しい実行ループに関連付けられていないことを意味します。初期化中とフォアグラウンドに戻るときに、メソッド setupNotificationTimer() が異なる実行ループで呼び出される可能性がありますか? (つまり、別のスレッドまたは同様のコンテキストで)

このコードは問題を回避します。

NSTimer* timer = [NSTimer timerWithTimeInterval:[[timerDetails objectForKey:@"interval"] floatValue]
                                 target:self
                               selector:@selector(fireTimer:)
                               userInfo:timerDetails
                                repeats:repeat];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

これにより、タイマーがメインの実行ループでスケジュールされ、起動することが保証されます。

于 2013-04-03T11:27:07.320 に答える