在Objective-C中花费时间

时间:2009-04-12 14:12:09

标签: ios objective-c

我需要在两个事件之间花费时间,例如,UIView的出现和用户的第一反应。

如何在Objective-C中实现它?

7 个答案:

答案 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时间可以随时向前或向后跳跃。