iOS how to call a method on the minute, every minute

大城市里の小女人 提交于 2020-02-05 05:38:37

问题


I mean 12:01:00, 12:02:00 ...

In iOS7, I want to call a method when minute of time is changed. In other words, if now is 01:55:47, then I want to call a method at 01:56:00 -> 01:57:00 -> 01:58:00 ...

All I found about call a method is just about TimeInterval, but not I want.

I've tried this code:

NSTimeInterval roundedInterval = round([[NSDate date] timeIntervalSinceReferenceDate] / 60.0) * 60.0;
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:roundedInterval];

NSTimer *timer = [[NSTimer alloc] initWithFireDate:date
                                          interval:60.0
                                            target:self
                                          selector:@selector(handleEveryMinutes:)
                                          userInfo:nil
                                           repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

- (void)handleEveryMinutes:(NSTimer *)timer {
NSLog(@"one minute!");
}

But this method is not called at second 0.

Hope cool people can help me!

----- My answer -------

I also figure out why my code is not working correctly, I need add extra 60 seconds to the roundedInterval, which is the exact time of the next minute. If do not add 60 second, the fireDate is passed, so when I run my app, it have to fire immediately.

NSTimeInterval roundedInterval = round([[NSDate date] timeIntervalSinceReferenceDate] / 60.0) * 60.0 + 60; // the extra 60 is used to set the correct time Interval between next minute and referenced date.
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:roundedInterval];

Now, it's working!


回答1:


The key is to start that recurring timer at the right time. Get the current time and find out how many seconds we are into the current minute...

NSDateComponents *components = [[NSCalendar currentCalendar] components: NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger second = [components second];

From this we can get the number of seconds until the next minute...

NSInteger tillNextMinute = (60 - second) % 60;

I haven't tested that, but the idea of the mod 60 is to handle the case when second is zero. Now we're almost done...

[self performSelector:@selector(startTimer) withObject:nil afterDelay:tillNextMinute];

Then the code you began with...

- (void)startTimer {
    // contains the code you posted to start the timer
}



回答2:


The currently accepted answer will be incorrect by up to 1 second.

Here is how to get the next minute as precisely as possible:

// set clock to current date
NSDate *date = [NSDate date];
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSSecondCalendarUnit fromDate:date];

NSTimeInterval timeSinceLastSecond = date.timeIntervalSince1970 - floor(date.timeIntervalSince1970);
NSTimeInterval timeToNextMinute = (60 - dateComponents.second) - timeSinceLastSecond;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeToNextMinute * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

  [self handleEveryMinutes:nil];

});


来源:https://stackoverflow.com/questions/22243638/ios-how-to-call-a-method-on-the-minute-every-minute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!