J'ai besoin d'obtenir le temps écoulé entre deux événements, par exemple, l'apparition d'un UIView et la première réaction de l'utilisateur.
Comment puis-je y parvenir en Objective-C?
ios
objective-c
Ilya Suzdalnitski
la source
la source
fabs(...)
pour obtenir la valeur absolue d'un flottant. Par exemple.NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);
[NSDate date]
peut conduire à des bogues difficiles à suivre, voir cette réponse pour plus d'informations.Vous ne devez pas vous en remettre à
[NSDate date]
des fins de chronométrage car il peut sur-ou sous-déclarer le temps écoulé. Il y a même des cas où votre ordinateur va apparemment voyager dans le temps car le temps écoulé sera négatif! (Par exemple, si l'horloge a reculé pendant le chronométrage.)Selon Aria Haghighi dans la conférence "Advanced iOS Gesture Recognition" du cours Winter 2013 Stanford iOS (34:00), vous devriez utiliser
CACurrentMediaTime()
si vous avez besoin d'un intervalle de temps précis.Objectif c:
Rapide:
La raison en est que se
[NSDate date]
synchronise sur le serveur, cela peut donc conduire à des «hoquets de synchronisation temporelle» qui peuvent conduire à des bogues très difficiles à suivre.CACurrentMediaTime()
, d'autre part, est une heure de l'appareil qui ne change pas avec ces synchronisations réseau.Vous devrez ajouter le framework QuartzCore aux paramètres de votre cible.
la source
[NSDate date]
intérieur d'un bloc d'achèvement dans un bloc de répartition, j'obtenais la même heure "actuelle" que celle signalée[NSDate date]
juste avant que l'exécution n'atteigne le point auquel mes blocs ont été créés.CACurrentMediaTime()
résolu ce problème.CACurrentMediaTime()
cesse de clignoter lorsque l'appareil entre en veille. Si vous testez avec l'appareil déconnecté d'un ordinateur, verrouillez-le, puis attendez ~ 10 minutes, vous constaterez queCACurrentMediaTime()
cela ne correspond pas à l'heure de l'horloge murale.Utilisez la
timeIntervalSinceDate
méthodeNSTimeInterval
est juste undouble
, définissezNSDate
comme ceci:la source
Pour quiconque vient ici à la recherche d'une implémentation getTickCount () pour iOS, voici la mienne après avoir rassemblé diverses sources.
Auparavant, j'avais un bug dans ce code (je divisais d'abord par 1000000) qui provoquait une quantification de la sortie sur mon iPhone 6 (peut-être que ce n'était pas un problème sur iPhone 4 / etc ou je ne l'ai tout simplement jamais remarqué). Notez qu'en n'effectuant pas cette division en premier, il y a un risque de débordement si le numérateur de la base de temps est assez grand. Si quelqu'un est curieux, il y a un lien avec beaucoup plus d'informations ici: https://stackoverflow.com/a/23378064/588476
À la lumière de ces informations, il est peut-être plus sûr d'utiliser la fonction Apple
CACurrentMediaTime
!J'ai également évalué l'
mach_timebase_info
appel et cela prend environ 19ns sur mon iPhone 6, j'ai donc supprimé le code (non threadsafe) qui mettait en cache la sortie de cet appel.Soyez conscient du risque potentiel de dépassement de capacité en fonction de la sortie de l'appel de base de temps. Je soupçonne (mais je ne sais pas) que cela pourrait être une constante pour chaque modèle d'iPhone. sur mon iPhone 6 c'était
125/3
.La solution à l'aide
CACurrentMediaTime()
est assez triviale:la source
mach_timebase_info()
réinitialisera passémach_timebase_info_data_t
à{0,0}
avant de le définir sur les valeurs réelles, ce qui peut entraîner une division par zéro si le code est appelé à partir de plusieurs threads. Utilisez à ladispatch_once()
place (ouCACurrentMediaTime
qui est juste le temps mach converti en secondes).Pour les mesures de temps de précision (comme GetTickCount), jetez également un œil à mach_absolute_time et à ce Q&R Apple: http://developer.apple.com/qa/qa2004/qa1398.html .
la source
utilisez la fonction timeIntervalSince1970 de la classe NSDate comme ci-dessous:
en gros, c'est ce que j'utilise pour comparer la différence en secondes entre 2 dates différentes. vérifiez également ce lien ici
la source
Les autres réponses sont correctes (avec une mise en garde *). J'ajoute cette réponse simplement pour montrer un exemple d'utilisation:
Sur la console du débogueur, vous voyez quelque chose comme ceci:
* Avertissement: comme d'autres l'ont mentionné, utilisez
NSDate
pour calculer le temps écoulé uniquement à des fins occasionnelles. L'un de ces objectifs pourrait être des tests courants, un profilage brut, où vous voulez juste avoir une idée approximative de la durée d'une méthode.Le risque est que le réglage de l'heure actuelle de l'horloge de l'appareil puisse changer à tout moment en raison de la synchronisation de l'horloge du réseau. Le
NSDate
temps pouvait donc avancer ou reculer à tout moment.la source