Necesito obtener el tiempo transcurrido entre dos eventos, por ejemplo, la aparición de una UIView y la primera reacción del usuario.
¿Cómo puedo lograrlo en Objective-C?
ios
objective-c
Ilya Suzdalnitski
fuente
fuente
fabs(...)
para obtener el valor absoluto de un flotador. P.ej.NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);
[NSDate date]
puede conducir a errores difíciles de rastrear, vea esta respuesta para obtener más información.No debe confiar en él
[NSDate date]
para fines de tiempo ya que puede informar en exceso o por debajo del tiempo transcurrido. ¡Incluso hay casos en los que su computadora aparentemente viajará en el tiempo ya que el tiempo transcurrido será negativo! (Por ejemplo, si el reloj se movió hacia atrás durante el tiempo).De acuerdo con Aria Haghighi en la conferencia "Reconocimiento avanzado de gestos iOS" del curso de invierno 2013 Stanford iOS (34:00), debe usarla
CACurrentMediaTime()
si necesita un intervalo de tiempo preciso.C objetivo:
Rápido:
La razón es que se
[NSDate date]
sincroniza en el servidor, por lo que podría provocar "problemas de sincronización de tiempo" que pueden conducir a errores muy difíciles de rastrear.CACurrentMediaTime()
, por otro lado, es un tiempo de dispositivo que no cambia con estas sincronizaciones de red.Deberá agregar el marco QuartzCore a la configuración de su objetivo.
fuente
[NSDate date]
dentro de un bloque de finalización dentro de un bloque de despacho, recibía el mismo tiempo "actual" que informaba[NSDate date]
inmediatamente antes de que la ejecución llegara al punto en el que se crearon mis bloques.CACurrentMediaTime()
resuelto este problemaCACurrentMediaTime()
deja de hacer tictac cuando el dispositivo entra en suspensión. Si prueba con el dispositivo desconectado de una computadora, bloquéelo, luego espere ~ 10 minutos y verá queCACurrentMediaTime()
no cumple con la hora del reloj de pared.Usa el
timeIntervalSinceDate
métodoNSTimeInterval
es solo undouble
, definirNSDate
así:fuente
Para cualquiera que venga aquí en busca de una implementación getTickCount () para iOS, aquí está el mío después de juntar varias fuentes.
Anteriormente tenía un error en este código (primero lo dividí por 1000000) que estaba causando cierta cuantificación de la salida en mi iPhone 6 (tal vez esto no fue un problema en el iPhone 4 / etc o simplemente nunca lo noté). Tenga en cuenta que al no realizar esa división primero, existe cierto riesgo de desbordamiento si el numerador de la base de tiempo es bastante grande. Si alguien tiene curiosidad, hay un enlace con mucha más información aquí: https://stackoverflow.com/a/23378064/588476
A la luz de esa información, ¡quizás sea más seguro usar la función de Apple
CACurrentMediaTime
!También
mach_timebase_info
comparé la llamada y toma aproximadamente 19ns en mi iPhone 6, así que eliminé el código (no seguro) que estaba almacenando en caché la salida de esa llamada.Tenga en cuenta el riesgo potencial de desbordamiento dependiendo de la salida de la llamada a la base de tiempo. Sospecho (pero no sé) que podría ser una constante para cada modelo de iPhone. en mi iPhone 6 lo fue
125/3
.La solución usando
CACurrentMediaTime()
es bastante trivial:fuente
mach_timebase_info()
se restablecerá pasado enmach_timebase_info_data_t
que{0,0}
antes de que a los valores reales, que pueden causar la división por cero si el código es llamado desde varios subprocesos. Use en sudispatch_once()
lugar (oCACurrentMediaTime
que es solo tiempo de máquina convertido a segundos).Para medidas de tiempo precisas (como GetTickCount), también eche un vistazo a mach_absolute_time y este Q&A de Apple: http://developer.apple.com/qa/qa2004/qa1398.html .
fuente
use la función timeIntervalSince1970 de la clase NSDate como se muestra a continuación:
Básicamente, esto es lo que uso para comparar la diferencia en segundos entre 2 fechas diferentes. también revise este enlace aquí
fuente
Las otras respuestas son correctas (con una advertencia *). Agrego esta respuesta simplemente para mostrar un ejemplo de uso:
En la consola del depurador, verá algo como esto:
* Advertencia: como otros han mencionado, úselo
NSDate
para calcular el tiempo transcurrido solo para fines casuales. Uno de esos propósitos podría ser la prueba común, la elaboración de perfiles en bruto, donde solo desea una idea aproximada de cuánto tiempo lleva un método.El riesgo es que la configuración de la hora actual del reloj del dispositivo podría cambiar en cualquier momento debido a la sincronización del reloj de la red. Entonces el
NSDate
tiempo podría saltar hacia adelante o hacia atrás en cualquier momento.fuente