Мне нужно, чтобы прошло время между двумя событиями, например, появлением UIView и первой реакцией пользователя.
Как я могу достичь этого в Objective-C?
ios
objective-c
Илья Суздальницкий
источник
источник
fabs(...)
чтобы получить абсолютное значение с плавающей точкой. Например.NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);
[NSDate date]
может привести к трудностям в отслеживании ошибок, см. Этот ответ для получения дополнительной информации.Вы не должны полагаться на
[NSDate date]
сроки, поскольку это может привести к завышению или занижению прошедшего времени. Есть даже случаи, когда ваш компьютер будет путешествовать во времени, поскольку прошедшее время будет отрицательным! (Например, если часы переместились назад во время синхронизации.)Согласно Арии Хагиги в лекции «Расширенное распознавание жестов iOS» курса iOS 2013 года в Стэнфорде (34:00), вы должны использовать
CACurrentMediaTime()
если вам нужен точный интервал времени.Objective-C:
Swift:
Причина в том, что
[NSDate date]
синхронизация на сервере такова, что это может привести к «сбоям синхронизации по времени», что может привести к очень трудным для отслеживания ошибкам.CACurrentMediaTime()
с другой стороны, это время устройства, которое не изменяется при этих сетевых синхронизации.Вам нужно будет добавить платформу QuartzCore в настройки вашей цели.
источник
[NSDate date]
внутри блока завершения в блоке отправки я получал то же самое «текущее» время, о котором сообщалось[NSDate date]
непосредственно перед тем, как выполнение достигло точки, в которой были созданы мои блоки.CACurrentMediaTime()
решил эту проблему.CACurrentMediaTime()
виду, что перестает тикать, когда устройство переходит в режим сна. Если вы тестируете устройство, отключенное от компьютера, заблокируйте его, а затем подождите ~ 10 минут, и вы обнаружите, чтоCACurrentMediaTime()
оно не идет в ногу со временем настенных часов.Используйте
timeIntervalSinceDate
методNSTimeInterval
это простоdouble
определить,NSDate
как это:источник
Для тех, кто приезжает сюда в поисках реализации getTickCount () для iOS, вот мое после объединения различных источников.
Ранее у меня была ошибка в этом коде (сначала я разделил на 1000000), которая приводила к некоторому количественному определению выходных данных на моем iPhone 6 (возможно, это не было проблемой на iPhone 4 / etc или я просто никогда этого не замечал). Обратите внимание, что если сначала не выполнить это деление, существует некоторый риск переполнения, если числитель временной базы достаточно велик. Если кому-то интересно, здесь есть ссылка с гораздо большей информацией: https://stackoverflow.com/a/23378064/588476
В свете этой информации, возможно, безопаснее использовать функцию Apple
CACurrentMediaTime
!Я также
mach_timebase_info
протестировал вызов, и на моем iPhone 6 это заняло приблизительно 19 нс, поэтому я удалил (не поддерживающий потоки) код, который кэшировал выходные данные этого вызова.Помните о потенциальном риске переполнения в зависимости от выходных данных вызова временной базы. Я подозреваю (но не знаю), что она может быть постоянной для каждой модели iPhone. на моем айфоне 6 было
125/3
.Использование решения
CACurrentMediaTime()
довольно тривиально:источник
mach_timebase_info()
сбросит переданный вmach_timebase_info_data_t
перед{0,0}
тем, как установить его в фактические значения, что может вызвать деление на ноль, если код вызывается из нескольких потоков. Используйтеdispatch_once()
вместо этого (илиCACurrentMediaTime
которое является просто временем Маха, преобразованным в секунды).Для измерения времени точного прохождения (например, GetTickCount) также взгляните на mach_absolute_time и вопросы и ответы Apple: http://developer.apple.com/qa/qa2004/qa1398.html .
источник
используйте функцию timeIntervalSince1970 класса NSDate, как показано ниже:
в основном, это то, что я использую, чтобы сравнить разницу в секундах между двумя разными датами. также проверьте эту ссылку здесь
источник
Другие ответы верны (с оговоркой *). Я добавляю этот ответ просто, чтобы показать пример использования:
На консоли отладчика вы видите что-то вроде этого:
* Предостережение: как уже упоминалось, используйте
NSDate
для расчета прошедшего времени только для случайных целей. Одной из таких целей может быть обычное тестирование, грубое профилирование, когда вы просто хотите получить приблизительное представление о том, сколько времени занимает метод.Риск состоит в том, что текущая установка времени устройства может измениться в любой момент из-за синхронизации сетевых часов. Так что
NSDate
время может прыгать вперед или назад в любой момент.источник