Вам было бы лучше:
- получение текущей даты;
- работает, когда сегодня полночь;
- планирование таймера однократного срабатывания через день после этого; и
- повторение
Соблазнительно просто запланировать повторяющийся таймер, который сначала срабатывает с датой, рассчитанной в (3), и, следовательно, каждые 24 часа, но это не позволит обеспечить переход на летнее время. Так, например, (закодировано прямо здесь, не проверено)
- (void)scheduleNextTimedAction
{
// get the date now and the calendar the user is using
// (which will include their time zone, helpfully)
NSDate *dateNow = [NSDate date];
NSCalendar *relevantCalendar = [NSCalendar currentCalendar];
// decompose the current date to components; we'll
// just ask for month, day and year here for brevity;
// check out the other calendar units to decide whether
// that's something you consider acceptable
NSDateComponents *componentsForNow =
[relevantCalendar components:
NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:dateNow];
// we could explicitly set the time to midnight now,
// but since that's 00:00 it'll already be the value
// in the date components per the standard Cocoa object
// creation components, so...
// get the midnight that last occurred
NSDate *lastMidnight = [relevantCalendar dateFromComponents:componentsForNow];
// can we just add 24 hours to that? No, because of DST. So...
// create components that specify '1 day', however long that may be
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
oneDay.day = 1;
// hence ask the calendar what the next midnight will be
NSDate *nextMidnight = [relevantCalendar
dateByAddingComponents:oneDay
toDate:lastMidnight
options:0];
[oneDay release];
// now create a timer to fire at the next midnight, to call
// our periodic function. NB: there's no convenience factory
// method that takes an NSDate, so we'll have to alloc/init
NSTimer *timer = [[NSTimer alloc]
initWithFireDate:nextMidnight
interval:0.0 // we're not going to repeat, so...
target:self
selector:@selector(doTimedAction:)
userInfo:nil
repeats:NO];
// schedule the timer on the current run loop
[[NSRunLoop currentRunLoop]
addTimer:timer
forMode: NSDefaultRunLoopMode];
// timer is retained by the run loop, so we can forget about it
[timer release];
}
- (void)doTimedAction:(NSTimer *)timer
{
NSLog(@"do action");
[self scheduleNextTimedAction];
}