我正在尋找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