2009-04-12 15 views

risposta

254
NSDate *start = [NSDate date]; 
// do stuff... 
NSTimeInterval timeInterval = [start timeIntervalSinceNow]; 

timeInterval è la differenza tra partenza ed ora, in secondi, con precisione sub-millisecondo.

+1

+1, Risposta buona e orientale. Grazie. :) – mAc

+5

quindi è un valore negativo se ho capito correttamente –

+18

@NicolasZozol puoi usare 'fabs (...)' per ottenere il valore assoluto di un float. Per esempio. 'NSTimeInterval timeInterval = fabs ([start timeIntervalSinceNow]);' –

5

utilizzare la funzione timeIntervalSince1970 della classe NSDate come di seguito:

double start = [startDate timeIntervalSince1970]; 
double end = [endDate timeIntervalSince1970]; 
double difference = end - start; 

in fondo, questo è quello che uso per confrontare la differenza in secondi tra 2 date differenti. controllare anche questo link here

23

utilizzare il metodo timeIntervalSinceDate

NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate]; 

NSTimeInterval è solo un double, definire in NSDate come questo:

typedef double NSTimeInterval; 
14

Per chiunque di venire qui in cerca di un'implementazione GetTickCount() per iOS, ecco il mio dopo aver messo insieme varie fonti:

#include <mach/mach.h> 
#include <mach/mach_time.h> 

uint64_t getTickCount(void) 
{ 
    static mach_timebase_info_data_t sTimebaseInfo; 
    uint64_t machTime = mach_absolute_time(); 

    // Convert to nanoseconds - if this is the first time we've run, get the timebase. 
    if (sTimebaseInfo.denom == 0) 
    { 
     (void) mach_timebase_info(&sTimebaseInfo); 
    } 

    // Convert the mach time to milliseconds 
    uint64_t millis = ((machTime/1000000) * sTimebaseInfo.numer)/sTimebaseInfo.denom; 
    return millis; 
} 
+0

Qualcuno sa perché c'è un cast ridondante (vuoto) sulla chiamata mach_timebase_info? –

+0

@SimonTillson questa è una buona domanda: o era necessario silenziare un avviso, o l'ho copiato da qualche altra parte e semplicemente non ho notato di cancellarlo. Non riesco a ricordare. –

200

Non si deve fare affidamento su [NSDate date] per motivi di temporizzazione poiché può sovrascrivere o sottovalutare il tempo trascorso. Ci sono persino casi in cui il tuo computer sembrerà viaggiare nel tempo poiché il tempo trascorso sarà negativo! (Ad esempio, se l'orologio si sposta all'indietro durante i tempi.)

Secondo Aria Haghighi nella conferenza "Advanced iOS Gesture Recognition" dello Winter 2013 Stanford iOS course (34:00), è necessario utilizzare CACurrentMediaTime() se è necessario un intervallo di tempo preciso.

Objective-C:

#import <QuartzCore/QuartzCore.h> 
CFTimeInterval startTime = CACurrentMediaTime(); 
// perform some action 
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime; 

Swift:

let startTime = CACurrentMediaTime() 
// perform some action 
let elapsedTime = CACurrentMediaTime() - startTime 

La ragione è che [NSDate date] sincronizza sul server, in modo che potesse portare a "singhiozzo Time-Sync" che può portare a bug molto difficili da tracciare. CACurrentMediaTime(), d'altra parte, è un orario del dispositivo che non cambia con questi sincronismi di rete.

È necessario add il QuartzCore framework per le impostazioni del target.

+14

Si prega di aggiornare questo. Anche se penso che tutti possano essere d'accordo sul fatto che NSDate dovrebbe essere la tua prima opzione, questo suggerimento ha risolto un mio problema. Quando chiamavo '[data NSDate]' all'interno di un blocco di completamento all'interno di un blocco di invio, ricevevo lo stesso tempo "corrente" che veniva segnalato da "[data NSDate]" immediatamente prima che l'esecuzione colpisse il punto in cui i miei blocchi erano stati creati. 'CACurrentMediaTime()' ha risolto questo problema. – n00neimp0rtant

+0

Come useremmo il tempo trascorso per la visualizzazione come mm: ss? – CyberMew

+0

Perché non ne ho mai sentito parlare ... – Morkrom

1

Altre risposte sono corrette (con un avvertimento *).Aggiungo questa risposta semplicemente per mostrare un esempio di utilizzo:

- (void)getYourAffairsInOrder 
{ 
    NSDate* methodStart = [NSDate date]; // Capture start time. 

    // … Do some work … 

    NSLog(@"DEBUG Method %s ran. Elapsed: %f seconds.", __func__, -([methodStart timeIntervalSinceNow])); // Calculate and report elapsed time. 

}

Sul debugger console, si vede qualcosa di simile:

DEBUG Method '-[XMAppDelegate getYourAffairsInOrder]' ran. Elapsed: 0.033827 seconds. 

* Caveat: Come altri hanno detto , utilizzare NSDate per calcolare il tempo trascorso solo per scopi casuali. Uno di questi potrebbe essere un test comune, una profilazione grezza, in cui si desidera solo un'idea approssimativa di quanto tempo impiega un metodo.

Il rischio è che l'impostazione dell'orario corrente dell'orologio del dispositivo possa cambiare in qualsiasi momento a causa della sincronizzazione dell'orologio di rete. Quindi il tempo NSDate potrebbe saltare avanti o indietro C in qualsiasi momento.

Problemi correlati