Ios 获取Objective-C中经过的时间
我需要获得两个事件之间经过的时间,例如,UIView的外观和用户的第一反应 我如何在目标C中实现它Ios 获取Objective-C中经过的时间,ios,objective-c,Ios,Objective C,我需要获得两个事件之间经过的时间,例如,UIView的外观和用户的第一反应 我如何在目标C中实现它 NSDate *start = [NSDate date]; // do stuff... NSTimeInterval timeInterval = [start timeIntervalSinceNow]; timeInterval是开始和现在之间的差值,以秒为单位,精度为亚毫秒。使用NSDate类的timeintervalnce1970函数,如下所示: double start = [st
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];
timeInterval
是开始和现在之间的差值,以秒为单位,精度为亚毫秒。使用NSDate类的timeintervalnce1970函数,如下所示:
double start = [startDate timeIntervalSince1970];
double end = [endDate timeIntervalSince1970];
double difference = end - start;
基本上,这就是我用来比较两个不同日期之间秒数差异的方法。还可以查看此链接查看percise时间测量值(如GetTickCount),还可以查看马赫绝对时间和此Apple问答:。使用
timeIntervalSinceDate
方法
NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];
NSTimeInterval
只是一个double
,在NSDate
中定义如下:
typedef double NSTimeInterval;
DEBUG Method '-[XMAppDelegate getYourAffairsInOrder]' ran. Elapsed: 0.033827 seconds.
对于来这里寻找iOS的getTickCount()实现的任何人来说,在汇集了各种来源之后,这里是我的 之前,我在这段代码中有一个bug(我先除以1000000),导致我的iPhone 6上的输出出现了一些量化(可能这在iPhone 4/etc上不是问题,或者我从来没有注意到)。请注意,如果不首先执行该除法,则如果时基的分子相当大,则存在溢出的风险。如果有人好奇,这里有一个链接,提供更多信息: 根据这些信息,也许使用苹果的函数
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;
}
您不应该依赖于
[NSDate date]
来计时,因为它可能会超过或低于所经过的时间。甚至在某些情况下,您的计算机似乎会进行时间旅行,因为经过的时间是负数!(例如,如果时钟在计时过程中向后移动。)
根据Aria Haghhii在(34:00)的“高级iOS手势识别”讲座中的说法,如果需要准确的时间间隔,应该使用
目标C:
#import <QuartzCore/QuartzCore.h>
斯威夫特:
let startTime = CACurrentMediaTime()
// perform some action
let elapsedTime = CACurrentMediaTime() - startTime
原因是[NSDate date]
在服务器上同步,因此可能会导致“时间同步打嗝”,从而导致很难跟踪错误<另一方面,code>CACurrentMediaTime()是一个设备时间,它不会随着这些网络同步而改变
您将需要根据目标的设置重新设置
注意:还有其他API,比如
clock\u gettime\u nsec\u np
,也可以工作。其他答案是正确的(有一个警告*)。我添加此答案只是为了显示示例用法:
- (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.
}
在调试器控制台上,您可以看到如下内容:
typedef double NSTimeInterval;
DEBUG Method '-[XMAppDelegate getYourAffairsInOrder]' ran. Elapsed: 0.033827 seconds.
*警告:正如其他人所提到的,使用
NSDate
计算经过的时间仅用于偶然目的。其中一个目的可能是普通测试,即粗略的评测,您只想大致了解一个方法需要多长时间
风险在于,由于网络时钟同步,设备时钟的当前时间设置可能随时发生变化。因此,
NSDate
时间可以在任何时刻向前或向后跳跃。@NicolasZozol您可以使用fabs(…)
获取浮点的绝对值。例如,NSTimeInterval timeInterval=fabs([start timeIntervalSinceNow])
似乎时间间隔的值为负值。如果得到负值-乘以-1,那么依赖[NSDate date]
可能会导致难以跟踪错误,请参阅以获取更多信息。@pinkflocks-什么?负值是如何合法地出现的?有人知道为什么在mach_timebase_info call上有多余的(无效)强制转换吗?@SimonTillson这是一个好问题-要么它被要求使警告静音,要么我从其他地方复制了它,只是没有注意到要删除它。我不记得了,这不是线程安全的mach\u timebase\u info()
将在将其设置为实际值之前,将传入的mach\u timebase\u info\u data\t
重置为{0,0}
,如果从多个线程调用代码,可能会导致被零除。改用dispatch_once()
(或者CACurrentMediaTime
,它只是马赫时间转换成秒数)。谢谢@wonder.mices,我已经更新了我的答案(也发现了量化方面的问题,我责怪6岁的我…)请对此进行投票。虽然我认为每个人都同意NSDate应该是你的第一选择,但这个建议解决了我的一个问题。在调度块内的完成块内调用[NSDate date]
时,我得到的“当前”时间与[NSDate date]
在执行到达创建我的块的点之前报告的时间相同CACurrentMediaTime()
解决了这个问题。我们如何使用延迟时间来显示mm:ss?@CyberMew:这是另一个问题。有关一些解决方案,请参阅。请注意,当设备进入睡眠状态时,CACurrentMediaTime()
会停止滴答声。如果在设备与计算机断开连接的情况下进行测试,请将其锁定,然后等待约10分钟,您会发现CACurrentMediaTime()
无法跟上挂钟时间。添加并导入#导入