Как я могу получить уведомление об изменении системного времени в моем приложении Какао?

У меня есть приложение Какао, которое записывает даты на события. Мне нужно знать, когда системное время сбрасывается и на сколько, но я, кажется, не могу оштрафовать уведомление в любом месте, которое говорит мне, что такое произошло. Это изменение может произойти, потому что NTP сбрасывает часы или потому что пользователь сбрасывает (например, из Системных настроек). Было бы здорово, если бы был только NSNotification Я мог бы зарегистрироваться, чтобы получить, но я открыт для любых предложений.

4 ответа

Решение

Apple добавлена ​​в NSSystemClockDidChangeNotification, часть NSDate, в Snow Leopard (10.6). Кажется, нет способа сделать это в Leopard (10.5) или ранее. Согласно Apple NSDate документы:

Отправляется всякий раз, когда меняются системные часы. Это может быть инициировано вызовом settimeofday() или изменением пользователем значений на панели предпочтений даты и времени. Объект уведомления пуст. Это уведомление не содержит словаря userInfo.

Это не говорит вам, "сколько" времени изменилось. Вы можете рассчитывать это периодически (скажем, каждые 5 секунд в NSTimer) захват системного времени с [NSDate date], сохраняя его в переменную, а затем после NSSystemClockDidChangeNotification пожары, возьмите новую дату и сравните их вместе, используя NSDate's timeIntervalSinceDate: способ получить разницу.

Не с точностью до миллисекунды или даже секунды, но довольно близко.

РЕДАКТИРОВАТЬ: см. Этот пост. Вы могли бы использовать UpTime() Команда C для захвата времени работы системы в тиках процессора (которые вы можете позже преобразовать в секунды). Вы можете использовать это, чтобы выяснить, сколько времени изменилось (при условии отсутствия перезагрузки системы или сна). Это работает, даже если системные часы изменяются пользовательским или сетевым протоколом времени.

Если кто-то ищет решение, узнайте событие изменения системной даты с 10.4.


OSStatus DateChangeEventHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData) 
{
    NSLog(@"Event received!\n");    
    return 0;
}


- (void)SystemTimeChangeHandler
{
    EventTypeSpec eventType;
    eventType.eventClass = kEventClassSystem;
    eventType.eventKind = kEventSystemTimeDateChanged;

    EventHandlerUPP eventHandlerUPP =
    NewEventHandlerUPP(DateChangeEventHandler);
    EventHandlerRef eventHandlerRef = NULL;
    (void)InstallApplicationEventHandler(
                                         eventHandlerUPP,
                                         1,
                                         &eventType,
                                         self,
                                         &eventHandlerRef);

}

Время движется постоянно. Уведомление каждый раз, когда текущее время изменяется, будет постоянным, пропитывающим процессор потоком уведомлений.

Что вам нужно сделать, это получить текущее время в вашем обработчике событий - тот, который получает события, на которые вы ставите метки. Вы получите текущее время, позвонив [NSDate date],

Я не думаю, что есть единственный способ сделать это из-за различных механизмов, с помощью которых время может измениться. Но это не будет очень дорого (слишком дорого? Не знаю, вы его уже профилировали?;-), чтобы установить NSTimer один раз в секунду, чтобы проверить время и сравнить его с предыдущим значением. Если он не продвинется примерно на секунду, произошло что-то интересное, и вы можете уведомить свой объект аудита.

Другие вопросы по тегам