当前位置:  开发笔记 > 前端 > 正文

在Objective-C中花费时间

如何解决《在Objective-C中花费时间》经验,为你挑选了5个好方法。

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

如何在Objective-C中实现它?



1> Can Berk Güd..:
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];

timeInterval 是start和now之间的差异,以秒为单位,精确到亚毫秒级.


@NicolasZozol你可以使用`fabs(...)`来获得浮点数的绝对值.例如.`NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);`
依靠"[NSDate date]"可能导致难以跟踪错误,请参阅[此答案](http://stackoverflow.com/a/17986909/35690)以获取更多信息.
所以如果我理解正确,这是一个负值

2> Senseful..:

您不应该依赖于[NSDate date]计时目的,因为它可能会超过或低于报告已用时间.甚至有些情况下,您的计算机似乎是时间旅行,因为经过的时间将是负面的!(例如,如果时钟在计时期间向后移动.)

根据Aria Haghighi在2013年冬季斯坦福iOS课程(34:00)的"高级iOS手势识别"讲座中的说法,CACurrentMediaTime()如果您需要准确的时间间隔,则应该使用.

Objective-C的:

#import 
CFTimeInterval startTime = CACurrentMediaTime();
// perform some action
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;

迅速:

let startTime = CACurrentMediaTime()
// perform some action
let elapsedTime = CACurrentMediaTime() - startTime

原因是[NSDate date]服务器上的同步,因此可能导致"时间同步打嗝",这可能导致非常难以跟踪的错误.CACurrentMediaTime()另一方面,设备时间不随这些网络同步而改变.

您将需要添加的QuartzCore框架到目标的设置.


请注意这一点.虽然我认为每个人都同意NSDate应该是你的第一选择,但这个建议解决了我的问题.在调度块中的完成块内调用"[NSDate date]"时,我在执行到创建块之前立即获得"[NSDate date]"报告的"当前"时间.`CACurrentMediaTime()`解决了这个问题.
请注意,当设备进入睡眠状态时,"CACurrentMediaTime()"会停止滴答声.如果您在断开计算机设备的情况下进行测试,请将其锁定,然后等待~10分钟,您会发现`CACurrentMediaTime()`无法跟上挂钟时间.

3> Marco Lazzer..:

使用该timeIntervalSinceDate方法

NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];

NSTimeInterval只是一个double,定义NSDate如下:

typedef double NSTimeInterval;



4> Wayne Uroda..:

对于任何来到这里寻找iOS的getTickCount()实现的人来说,将各种来源放在一起之后,这是我的.

以前我在这段代码中有一个错误(我首先除以1000000),这导致iPhone 6上的输出量化(也许这不是iPhone 4 /等上的问题,或者我从未注意到它).请注意,如果不首先执行该除法,如果时基的分子非常大,则存在一些溢出的风险.如果有人好奇,可以在这里找到更多信息的链接:https://stackoverflow.com/a/23378064/588476

根据这些信息,使用Apple的功能可能更安全CACurrentMediaTime!

我也对该mach_timebase_info调用进行了基准测试,我的iPhone 6上需要大约19ns,所以我删除了(而不是线程安全的)代码,该代码缓存了该调用的输出.

#include 
#include 

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;
}


这不是线程安全的.`mach_timebase_info()`将把传入的`mach_timebase_info_data_t`重置为`{0,0}`,然后再将其设置为实际值,如果从多个线程调用代码,则可能导致除零.使用`dispatch_once()`代替(或'CACurrentMediaTime`,它只是马赫时间转换为秒).

5> Jason Coco..:

对于percise时间测量(如GetTickCount),还可以查看mach_absolute_time和Apple问答:http://developer.apple.com/qa/qa2004/qa1398.html.

推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有