我正在寻找iPhone的高分辨率时间码,以便做一些表演时机。我想这样写代码:适用于iPhone的高分辨率定时器?
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog(@"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime]);
我正在寻找iPhone的高分辨率时间码,以便做一些表演时机。我想这样写代码:适用于iPhone的高分辨率定时器?
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog(@"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime]);
查看mach/mach_time.h标题中的mach_absolute_time()。
请勿使用NSDate。当ntp做它的事情时,NSDate甚至不保证不会偶尔倒退。如果iOS设备漂移几秒钟,那么当NTP纠正这个漂移时,你会看到时钟突然倒退几秒钟,对于时间使用非常不利。mach_time使用计数器不曾经得到由NTP纠正,因此不能走回头路,因此是更好的时机。)
'NSDate'只返回一个自2001年1月1日以来的秒数。对于秒表计时,负的时间不会发生,所以我看不需要将'mach_absolute_time()'带入代码的开销 - [在这里实现](http://stackoverflow.com/a/12553393/111307)。 – bobobobo 2012-09-23 15:52:15
@bobobobo:设备自2001年1月1日以来的秒数偶尔会被NTP向后修正。因此,对于任何具有时钟漂移的时钟晶振,以及可以纠正漂移的网络连接,它都可以是非单调的。 – hotpaw2 2012-09-23 18:03:20
我结束了使用mach_absolute_time()。我发现了一个小班使用它,[这里](http://zpasternack.blogspot.com/2012/07/high-resolution-timing-in-cocoa.html)。 – zpasternack 2012-09-23 19:08:43
使用NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]
以在最后得到的开始时间,然后NSLog (@"Operation took %f seconds.", [NSDate timeIntervalSinceReferenceDate] - startTime);
。
完美的作品,谢谢!我没有意识到NSDate具有这种精度。 – zpasternack 2010-08-22 05:19:34
更好的选择是CACurrentMediaTime()
它使用mach_absolute_time()
但其转换为CFTimeInterval
(即时间,以秒为一双)给你。
需要['#import
下面是我使用mach_absolute_time()
(基于计算方法shown here和NSDate
)的时钟计时器的答案。在准确性方面实际上是相同的。
double machGetClockS()
{
static bool init = 0 ;
static mach_timebase_info_data_t tbInfo ;
static double conversionFactor ;
if(!init)
{
init = 1 ;
// get the time base
mach_timebase_info(&tbInfo) ;
conversionFactor = tbInfo.numer/(1e9*tbInfo.denom) ; // ns->s
}
return mach_absolute_time() * conversionFactor ; // seconds
}
double machGetClockDiffS()
{
static double lastTime = 0;
double currentTime = machGetClockS() ;
double diff = currentTime - lastTime ;
lastTime = currentTime ; // update for next call
return diff ; // that's your answer
}
double getClockS()
{
return [NSDate timeIntervalSinceReferenceDate] ; // NSTimeInterval is always specified in seconds
}
double getClockDiffS()
{
static double lastTime = 0 ;
double currentTime = getClockS() ;
double diff = currentTime - lastTime ;
lastTime = currentTime ; // update for next call
return diff ; // that's your answer
}
注意在这两个分辨率才是真的好。
IOS SIMULATOR, running frame rate counts (in milliseconds (*1000.0)) MACH_ABS_TIME/NSTimeIntervals 58.557001/58.552980 40.558007/40.562987 52.207822/52.200019 33.742197/33.742011 38.498912/38.504004 48.872679/48.868001 45.012602/45.011997 57.858432/57.865977 25.044615/25.038004 IPAD HARDWARE SAMPLINGS: 33.415041/33.416033 33.240167/33.239007 33.357542/33.357978 33.302833/33.302009 33.506750/33.509016 33.582250/33.582985 33.233958/33.232987 33.239042/33.237994
*如果你看到这篇文章的编辑历史,你可以看到在double
的地方使用float
的危险!
为什么不使用'getrusage()'?任何在C中工作的东西都可以在Objective-C中工作。 – 2010-08-22 04:59:43
因为有一个完美的可可方法可以做同样的事情。 – lucius 2010-08-22 05:04:55