Мне нужно получить время, прошедшее между двумя событиями, например, появление UIView и первой реакции пользователя.
Как я могу достичь этого в Objective-C?
Мне нужно получить время, прошедшее между двумя событиями, например, появление UIView и первой реакции пользователя.
Как я могу достичь этого в Objective-C?
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];
timeInterval
- разница между началом и теперь, в секундах, с точностью до миллисекунды.
Вы не должны полагаться на [NSDate date]
в целях определения времени, так как он может over- или занижать прошедшее время. Есть даже случаи, когда ваш компьютер будет путешествовать во времени, так как прошедшее время будет отрицательным! (Например, если часы переместились назад во время.)
Согласно Арии Хагиги в лекции "Расширенное распознавание жестов iOS" курса iOS 2013 года в Стэнфорде (34:00), вам следует использовать CACurrentMediaTime()
если вам нужен точный интервал времени.
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
Причина в том, что [NSDate date]
синхронизируется на сервере, поэтому это может привести к " [NSDate date]
синхронизации по времени", что может привести к очень трудным для отслеживания ошибкам. CACurrentMediaTime()
, с другой стороны, это время устройства, которое не изменяется с этими сетевыми синхронизациями.
Вам нужно будет добавить платформу QuartzCore в ваши целевые настройки.
Использовать метод timeIntervalSinceDate
NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];
NSTimeInterval
является просто a double
, определите в NSDate
следующим образом:
typedef double NSTimeInterval;
Для тех, кто приезжает сюда в поисках реализации getTickCount() для iOS, вот мое после объединения различных источников.
Ранее у меня была ошибка в этом коде (сначала я разделил на 1000000), которая приводила к некоторому количественному определению выходных данных на моем iPhone 6 (возможно, это не было проблемой на iPhone 4/etc или я просто никогда этого не замечал). Обратите внимание, что если сначала не выполнить это деление, существует некоторый риск переполнения, если числитель временной базы достаточно велик. Если кому-то интересно, здесь есть ссылка с гораздо более подробной информацией: fooobar.com/questions/9807/...
В свете этой информации, возможно, безопаснее использовать функцию Apple CACurrentMediaTime
!
Я также mach_timebase_info
вызов mach_timebase_info, и на моем iPhone 6 это заняло примерно 19 нс, поэтому я удалил (не поточно-безопасный) код, который кэшировал выходные данные этого вызова.
#include <mach/mach.h>
#include <mach/mach_time.h>
uint64_t getTickCount(void)
{
mach_timebase_info_data_t sTimebaseInfo;
uint64_t machTime = mach_absolute_time();
// Convert to milliseconds
mach_timebase_info(&sTimebaseInfo);
machTime *= sTimebaseInfo.numer;
machTime /= sTimebaseInfo.denom;
machTime /= 1000000; // convert from nanoseconds to milliseconds
return machTime;
}
Помните о потенциальном риске переполнения в зависимости от выходных данных вызова временной базы. Я подозреваю (но не знаю), что она может быть постоянной для каждой модели iPhone. на моем 125/3
6 было 125/3
.
Решение с использованием CACurrentMediaTime()
довольно тривиально:
uint64_t getTickCount(void)
{
double ret = CACurrentMediaTime();
return ret * 1000;
}
Для измерений времени измерения (например, GetTickCount) также рассмотрите mach_absolute_time и этот Apple Q & A: http://developer.apple.com/qa/qa2004/qa1398.html. p >
используйте функцию timeIntervalSince1970 класса NSDate, как показано ниже:
double start = [startDate timeIntervalSince1970];
double end = [endDate timeIntervalSince1970];
double difference = end - start;
в основном это то, что я использую, чтобы сравнить разницу в секундах между двумя разными датами. также проверьте эту ссылку здесь
Другие ответы правильны (с оговоркой *). Я добавляю этот ответ просто, чтобы показать пример использования:
- (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.
}
На консоли отладчика вы увидите что-то вроде этого:
DEBUG Method '-[XMAppDelegate getYourAffairsInOrder]' ran. Elapsed: 0.033827 seconds.
* Предостережение. Как уже упоминалось, используйте NSDate
для вычисления прошедшего времени только для случайных целей. Одной из таких целей может быть обычное тестирование, сырое профилирование, где вам просто нужно грубое представление о том, как долго проходит метод.
Риск состоит в том, что установка времени текущего времени устройства устройства может измениться в любой момент из-за синхронизации сетевых часов. Таким NSDate
время NSDate
может двигаться вперед или назад в любой момент.