在Swift中准确测量时间以进行设备比较

时间:2015-04-11 21:28:51

标签: ios swift time

我需要能够记录反应时间,从屏幕加载或问题标签刷新到用户点击数字按钮。我没有找到Apple提供的文档,对此非常有帮助。 NSDate不够准确,我需要至少测量到几毫秒。 mach_absolute_time似乎受到游戏设计师的青睐,因为它在内部是一致的,但它不适用于这个应用程序,因为我需要跨设备比较数据,mach_absolute_time是CPU依赖的时间。 This Apple Dev Q&A建议使用NanosecondsToAbsoluteDurationToAbsolute,但它在obj-c中,我找不到快速的等效文档。

我有没有找到NanosecondsToAbsoluteDurationToAbsolute的快速版本?还有其他一些方法可以做到这一点吗?

以下是我试图将时间添加到的代码:

class EmotionQuestionsViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()

//mark "startTime" when view loads
    }

    @IBOutlet var questionLabel: UILabel!
    var timeResultsStack = [String]()

    var questionsStack = ["HAPPY", "ANXIOUS"]
    var questionResultsStack = [String]()
    var questionStackArrayIndex = 1

    @IBAction func RecordValueFromNumericalScaleOneToSeven(sender: UIButton) {

//mark durration time as currentTime - startTime, append to timeResultsStack

        let value = sender.currentTitle!
        questionResultsStack.append(value)

        if questionResultsStack.count < questionsStack.count{
            self.questionLabel.text = "how \(questionsStack[questionStackArrayIndex]) are you right now?"

//mark startTime when label is changed

            self.questionStackArrayIndex++

        }
        else{
            self.performSegueWithIdentifier("showResults", sender: nil)

        }
    }

3 个答案:

答案 0 :(得分:16)

如上所述,NSDate()的精确度可能已经足够了 为了你的目的。仅为了完整性,mach_absolute_time()来自引用的Technical Q&A QA1398 也适用于Swift:

let t1 = mach_absolute_time()
// do something
let t2 = mach_absolute_time()

let elapsed = t2 - t1
var timeBaseInfo = mach_timebase_info_data_t()
mach_timebase_info(&timeBaseInfo)
let elapsedNano = elapsed * UInt64(timeBaseInfo.numer) / UInt64(timeBaseInfo.denom);
print(elapsedNano)

此方法的可能优点:

  • 调用mach_absolute_time()似乎比调用快得多 NSDate().timeIntervalSinceReferenceDate,所以此方法可能是 更适合测量极短的间隔。
  • 如果调整时钟,NSDate()的值会发生变化, mach_absolute_time()没有这个问题。

答案 1 :(得分:3)

您可以使用NSTimeInterval来测量时间(比计时器好得多)。您只需要存储两个日期(两个时间点)并减去endTime - StartTime,如下所示:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var salesPriceSlider: UISlider!

    var startTime: NSTimeInterval = 0
    var endTime: NSTimeInterval = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        startTime = NSDate().timeIntervalSinceReferenceDate
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    @IBAction func stopTimeAction(sender: AnyObject) {
        endTime = NSDate().timeIntervalSinceReferenceDate
        println((endTime-startTime).time)
    }

}

extension NSTimeInterval {
    var time: String {
        return String(format:"%d:%02d:%02d.%03d", Int(self/3600.0), Int(self/60.0 % 60), Int(self % 60), Int(self*1000 % 1000))
    }
}

答案 2 :(得分:2)

NSDate与iOS和Mac设备上的实时时钟相关联,并具有亚毫秒精度。

使用NSDate的timeIntervalSinceReferenceDate方法将NSDate(或当前时间)转换为double,即自2001年1月1日以来的秒数,包括小数秒。一旦你这样做,你可以自由地对你得到的双打数学进行数学计算。