Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

ios - Measuring Time Accurately in Swift for Comparison Across Devices

I need to be able to record reaction time, from when the screen loads or the question label refreshes until the user taps a number button. I'm not finding documentation from Apple on this to be very helpful. NSDate is not accurate enough, I need to measure to milliseconds at least. mach_absolute_time seems to be favored by game designers because it is internally consistent, but it won't work for this application because I need to compare data across devices, and mach_absolute_time is CPU dependent time. This Apple Dev Q&A suggests using NanosecondsToAbsolute and DurationToAbsolute but it's in obj-c and I can't find a swift equivalent documentation.

Is there a swift version of NanosecondsToAbsolute and DurationToAbsolute that I'm just not finding? Some other way to do this consistently?

Here's the code I'm trying to add the times to:

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)

        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As already said, the precision of NSDate() is probably good enough for your purpose. Just for the sake of completeness, mach_absolute_time() from the referenced Technical Q&A QA1398 works in Swift as well:

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)

Possible advantages of this method:

  • Calling mach_absolute_time() seems to be much faster than calling NSDate().timeIntervalSinceReferenceDate, so this method might be better suited to measure extremely short intervals.
  • The value of NSDate() changes if the clock is adjusted, mach_absolute_time() does not have this problem.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...