2011-11-17 13 views
8

Ho un'applicazione che dovrebbe registrare alcune cose ogni 1 secondo e attualmente sto usando NSTimer, ma se la mia applicazione passa da una schermata all'altra (o quasi a qualsiasi altra cosa, davvero) rallenta un po 'il timer fare letture inesatte.Alternative NSTimer affidabili

Qual è un'alternativa affidabile da utilizzare? Il mio codice attuale è la seguente:

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(update) userInfo:nil repeats:YES]; 

risposta

12

NSTimer non è garantito per sparare esattamente in tempo, mai. Ma puoi usare un NSTimer in un modo molto più affidabile di quello che sei ora. Quando si utilizza scheduledTimerWithTimeInterval, viene creato un NSTimer che è pianificato nel ciclo di esecuzione per NSDefaultRunLoopMode. Questa modalità viene messa in pausa quando viene utilizzata l'interfaccia utente, pertanto i timer non si attivano in caso di interazione dell'utente. Per evitare questa pausa, utilizzare la modalità NSRunLoopCommonModes. Per fare ciò dovrai programmare tu stesso il timer in questo modo:

timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
+0

OK, lo cambierò ora. Invalido il timer allo stesso modo "[timer invalidate]'? – Baub

+0

Un timer creato in questo modo interagisce in modo identico. Tranne che devi aggiungerlo manualmente. Quando chiami invalido, dovrebbe essere rimosso automaticamente dal runloop come prima. – NJones

4

Si potrebbe:

  • Mettere il NSTimer in un thread diverso (che non può essere influenzata da l'interfaccia utente in questo modo)
  • ridurre l'intervallo (ad esempio 0,1 secondi) e, nella funzione di registrazione, verificare se è il momento "giusto" per registrare ciò che si desidera.
+0

non NSTimer crea il proprio nuovo thread ...? solo chiedendo ... ho letto da qualche parte che lo fa. –

+1

Non lo so, Steve Jobs. Dimmelo tu. ;) – Baub

+0

Ho provato a mettere il timer in un thread diverso chiamando 'performSelectorInBackground' ma non chiamerebbe il selettore quando è stato attivato (suppongo perché è in un thread diverso). – Baub