我怎样才能得到一个精确的时间,例如在Objective-C中以毫秒为单位?

有一个简单的方法来得到一个非常精确的时间?

我需要计算方法调用之间的一些延迟。 更具体地说,我想计算一个UIScrollView的滚动速度。

NSDatetimeIntervalSince*方法将返回一个NSTimeInterval ,它是一个具有亚毫秒精度的双精度值。 NSTimeInterval是在几秒钟内,但它使用双精度给你更大的精度。

为了计算毫秒的时间精度,你可以这样做:

 // Get a current time for where you want to start measuring from NSDate *date = [NSDate date]; // do work... // Find elapsed time and convert to milliseconds // Use (-) modifier to conversion since receiver is earlier than now double timePassed_ms = [date timeIntervalSinceNow] * -1000.0; 

timeIntervalSinceNow上的文档 。

有很多其他的方法来计算这个间隔使用NSDate ,我build议看看在NSDate类参考NSDate的类文档

mach_absolute_time()可用于获取精确的测量结果。

请参阅http://developer.apple.com/qa/qa2004/qa1398.html

也可以使用CACurrentMediaTime() ,它基本上是一样的,但是有一个更易于使用的界面。

请不要使用NSDateCFAbsoluteTimeGetCurrentgettimeofday来测量已用时间。 这些都取决于系统时钟,由于许多不同的原因,例如networking时间同步(NTP)更新时钟(经常发生漂移调整),DST调整,闰秒等等,可以随时更改系统时钟。

这意味着,如果你正在测量你的下载或上传速度,你会得到突然的高峰或下降的数字,与实际发生的事情不相关; 你的性能testing会有奇怪的不正确的离群值; 而您的手动定时器会在不正确的持续时间后触发。 时间甚至可能会倒退,最终会产生负面的变化,最终会产生无限的recursion或死代码(是的,我已经完成了这两个)。

使用mach_absolute_time 。 它测量自内核启动以来的真实秒数。 它单调递增(永远不会倒退),不受date和时间设置的影响。 由于这是一个痛苦的工作,这里有一个简单的包装,给你NSTimeInterval s:

 // LBClock.h @interface LBClock : NSObject + (instancetype)sharedClock; // since device boot or something. Monotonically increasing, unaffected by date and time settings - (NSTimeInterval)absoluteTime; - (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute; @end // LBClock.m #include <mach/mach.h> #include <mach/mach_time.h> @implementation LBClock { mach_timebase_info_data_t _clock_timebase; } + (instancetype)sharedClock { static LBClock *g; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ g = [LBClock new]; }); return g; } - (id)init { if(!(self = [super init])) return nil; mach_timebase_info(&_clock_timebase); return self; } - (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute { uint64_t nanos = (machAbsolute * _clock_timebase.numer) / _clock_timebase.denom; return nanos/1.0e9; } - (NSTimeInterval)absoluteTime { uint64_t machtime = mach_absolute_time(); return [self machAbsoluteToTimeInterval:machtime]; } @end 

CFAbsoluteTimeGetCurrent()将绝对时间作为double值返回,但我不知道它的精度是多less – 它可能只会每十几毫秒更新一次,也可能每微秒更新一次,我不知道。

我不会使用mach_absolute_time()因为它使用ticks(可能是正常运行时间)查询内核和处理器的绝对时间组合。

我会用什么:

 CFAbsoluteTimeGetCurrent(); 

此function经过优化,以纠正iOS和OSX软件和硬件的差异。

东西很热心

mach_absolute_time()AFAbsoluteTimeGetCurrent()差的商总是在24000011.154871附近

这是我的应用程序的日志:

请注意,最终结果时间是CFAbsoluteTimeGetCurrent()的差异

  2012-03-19 21:46:35.609 Rest Counter[3776:707] First Time: 353900795.609040 2012-03-19 21:46:36.360 Rest Counter[3776:707] Second Time: 353900796.360177 2012-03-19 21:46:36.361 Rest Counter[3776:707] Final Result Time (difference): 0.751137 2012-03-19 21:46:36.363 Rest Counter[3776:707] Mach absolute time: 18027372 2012-03-19 21:46:36.365 Rest Counter[3776:707] Mach absolute time/final time: 24000113.153295 2012-03-19 21:46:36.367 Rest Counter[3776:707] ----------------------------------------------------- 2012-03-19 21:46:43.074 Rest Counter[3776:707] First Time: 353900803.074637 2012-03-19 21:46:43.170 Rest Counter[3776:707] Second Time: 353900803.170256 2012-03-19 21:46:43.172 Rest Counter[3776:707] Final Result Time (difference): 0.095619 2012-03-19 21:46:43.173 Rest Counter[3776:707] Mach absolute time: 2294833 2012-03-19 21:46:43.175 Rest Counter[3776:707] Mach absolute time/final time: 23999753.727777 2012-03-19 21:46:43.177 Rest Counter[3776:707] ----------------------------------------------------- 2012-03-19 21:46:46.499 Rest Counter[3776:707] First Time: 353900806.499199 2012-03-19 21:46:55.017 Rest Counter[3776:707] Second Time: 353900815.016985 2012-03-19 21:46:55.018 Rest Counter[3776:707] Final Result Time (difference): 8.517786 2012-03-19 21:46:55.020 Rest Counter[3776:707] Mach absolute time: 204426836 2012-03-19 21:46:55.022 Rest Counter[3776:707] Mach absolute time/final time: 23999996.639500 2012-03-19 21:46:55.024 Rest Counter[3776:707] ----------------------------------------------------- 
 #define CTTimeStart() NSDate * __date = [NSDate date] #define CTTimeEnd(MSG) NSLog(MSG " %g",[__date timeIntervalSinceNow]*-1) 

用法:

 CTTimeStart(); ... CTTimeEnd(@"that was a long time:"); 

输出:

 2013-08-23 15:34:39.558 App-Dev[21229:907] that was a long time: .0023 

另外,下面是如何计算一个64位的NSNumber ,以毫秒为单位初始化Unix纪元,以防你如何将它存储在CoreData中。 我需要这个与我的应用程序相互作用的系统,这样的存储date。

  + (NSNumber*) longUnixEpoch { return [NSNumber numberWithLongLong:[[NSDate date] timeIntervalSince1970] * 1000]; } 

我知道这是一个古老的,但即使我发现自己再次徘徊,所以我想我会在这里提交自己的select。

最好的办法是查看我的博客文章: Objective-C中的定时事物:秒表

基本上,我写了一个类,停止看一个非常基本的方式,但封装,所以你只需要做到以下几点:

 [MMStopwatchARC start:@"My Timer"]; // your work here ... [MMStopwatchARC stop:@"My Timer"]; 

最后你会得到:

 MyApp[4090:15203] -> Stopwatch: [My Timer] runtime: [0.029] 

在日志中…

再次,看看我的post多一点或在这里下载: MMStopwatch.zip

对于那些我们需要@Jeff Thompson的Swift版答案的人:

 // Get a current time for where you want to start measuring from var date = NSDate() // do work... // Find elapsed time and convert to milliseconds // Use (-) modifier to conversion since receiver is earlier than now var timePassed_ms: Double = date.timeIntervalSinceNow * -1000.0 

我希望这可以帮助你。

您可以使用NSDate从1970年1月1日起以毫秒为单位获取当前时间:

 - (double)currentTimeInMilliseconds { NSDate *date = [NSDate date]; return [date timeIntervalSince1970]*1000; }