Ho un'applicazione Cocoa che registra i datestamp sugli eventi. Ho bisogno di sapere quando il tempo di sistema è resettato e da quanto, ma non riesco a sembrare una notifica da nessuna parte che mi dice che è successo qualcosa del genere. Questo cambiamento potrebbe accadere perché NTP resetta l'orologio o perché l'utente si resetta (ad esempio dalle Preferenze di Sistema). Sarebbe bello se ci fosse solo una NSNotification che potrei registrare per ricevere, ma sono aperto a qualsiasi suggerimento.Come posso ricevere una notifica di un cambio orario del sistema nella mia applicazione Cocoa?
risposta
Apple ha aggiunto in NSSystemClockDidChangeNotification, parte di NSDate, in Snow Leopard (10.6). Non sembra essere un modo per farlo in Leopard (10.5) o prima. Per il Apple NSDate docs:
Inviato ogni volta che si modifica l'orologio di sistema. Questo può essere avviato da una chiamata a settimeofday() o dall'utente che modifica i valori nel pannello Preferenza di data e ora. L'oggetto di notifica è null. Questa notifica non contiene un dizionario UserInfo.
Questo non sembra dirti "quanto" tempo è cambiato. È possibile calcolarlo periodicamente (ad esempio, ogni 5 secondi in un NSTimer) catturando l'ora del sistema con [Data NSDate], salvandolo in una variabile, quindi dopo l'attivazione di NSSystemClockDidChangeNotification, acquisisci la nuova data e confronta i due insieme utilizzando NSDate timeIntervalSinceDate: metodo per ottenere la differenza.
Non millisecondo o anche secondo accurato, ma piuttosto vicino.
MODIFICA: Vedere this post. È possibile utilizzare il comando C UpTime()
per ottenere il tempo di funzionamento del sistema in tic CPU (che in seguito è possibile convertire in secondi). Si può usare questo per capire quanto tempo è cambiato (supponendo che non ci sia il riavvio del sistema o il sonno). Funziona anche se l'orologio di sistema viene modificato dall'utente o dal protocollo orario di rete.
Il tempo si sposta costantemente. Una notifica ogni volta che viene modificata l'ora corrente sarebbe un flusso costante di notifiche di ammorbidimento della CPU.
Quello che devi fare è ottenere l'ora corrente nel gestore di eventi, quella che riceve gli eventi che stai registrando. Ottieni l'ora corrente chiamando [NSDate date]
.
Beh, non è ovvio che l'OP significhi un insolito cambio di orario e non il normale avanzamento dell'orologio :) – phlebotinum
Non penso che ci sia un unico modo per farlo a causa dei diversi meccanismi con cui il tempo potrebbe cambiare. Ma non sarebbe molto costoso (troppo costoso? Non lo so, lo hai già profilato? ;-) per impostare un NSTimer
una volta al secondo per controllare l'ora e confrontarlo con il valore precedente. Se non è avanzato di circa un secondo, è successo qualcosa di interessante e puoi notificare il tuo oggetto di controllo.
Se alcuni su è alla ricerca di una soluzione sanno sistema evento data cambiamento cambiamento da 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);
}
vuoi dire quando cambia orologio, per esempio tramite una sincronizzazione NTP o modificando il fuso orario o impostando manualmente l'ora in Preferenze di Sistema? –
Sì, questo è ciò che intendo. Mi dispiace di non essere stato molto chiaro all'inizio. Spero di aver reso questo più chiaro ora. –