我需要在两个事件之间花费时间,例如,UIView的出现和用户的第一反应。
如何在Objective-C中实现它?
答案 0 :(得分:261)
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];
timeInterval
是start和now之间的差异,以秒为单位,精确度为亚毫秒级。
答案 1 :(得分:220)
您不应该依赖[NSDate date]
进行计时,因为它可能会超过或低于报告已用时间。甚至有些情况下,您的计算机似乎是时间旅行,因为经过的时间将是负面的! (例如,如果时钟在计时期间向后移动。)
根据Aria Haghighi在Winter 2013 Stanford iOS course(34:00)的“高级iOS手势识别”讲座中的说法,如果您需要准确的时间间隔,则应使用CACurrentMediaTime()
。
目标-C:
#import <QuartzCore/QuartzCore.h>
CFTimeInterval startTime = CACurrentMediaTime();
// perform some action
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
夫特:
let startTime = CACurrentMediaTime()
// perform some action
let elapsedTime = CACurrentMediaTime() - startTime
原因是服务器上[NSDate date]
同步,因此可能导致“时间同步打嗝”,这可能导致非常难以跟踪的错误。另一方面,CACurrentMediaTime()
是设备时间,不随这些网络同步而改变。
您需要add QuartzCore framework到目标的设置。
答案 2 :(得分:23)
使用timeIntervalSinceDate
方法
NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];
NSTimeInterval
只是double
,在NSDate
中定义如下:
typedef double NSTimeInterval;
答案 3 :(得分:15)
对于任何来到这里寻找iOS的getTickCount()实现的人来说,将各种来源放在一起后,这是我的。
以前我在这段代码中有一个错误(我首先除以1000000),这导致iPhone 6上的输出量化(也许这不是iPhone 4 /等上的问题,或者我从未注意到它)。请注意,如果不首先执行该除法,如果时基的分子非常大,则存在一些溢出的风险。如果有人好奇,可以在这里找到更多信息的链接:https://stackoverflow.com/a/23378064/588476
根据这些信息,使用Apple的功能CACurrentMediaTime
可能更安全!
我还对mach_timebase_info
调用进行了基准测试,我的iPhone 6上大约需要19ns,因此我删除了缓存该调用输出的(非线程安全)代码。
#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型号的常量。在我的iPhone 6上它是125/3
。
使用CACurrentMediaTime()
的解决方案非常简单:
uint64_t getTickCount(void)
{
double ret = CACurrentMediaTime();
return ret * 1000;
}
答案 4 :(得分:8)
对于精确的时间测量(如GetTickCount),还要看看mach_absolute_time和Apple Q&amp; A:http://developer.apple.com/qa/qa2004/qa1398.html。
答案 5 :(得分:4)
使用NSDate类的timeIntervalSince1970函数,如下所示:
double start = [startDate timeIntervalSince1970];
double end = [endDate timeIntervalSince1970];
double difference = end - start;
基本上,这是我用来比较两个不同日期之间的秒差。另请查看此链接here
答案 6 :(得分:0)
其他答案是正确的(有警告*)。我添加此答案只是为了显示一个示例用法:
- (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
时间可以随时向前或向后跳跃。