Measuring Time Accurately in Swift for Comparison Across Devices

后端 未结 3 2080
暗喜
暗喜 2020-12-09 14:17

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 fro

相关标签:
3条回答
  • 2020-12-09 14:29

    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.
    0 讨论(0)
  • 2020-12-09 14:43

    You can use NSTimeInterval to measure time (much better than a timer). You just need to store two dates (two points in time) and subtract endTime - StartTime as follow:

    import UIKit
    
    class ViewController: UIViewController {
    
        var startTime: TimeInterval = 0
        var endTime: TimeInterval = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            startTime = Date().timeIntervalSinceReferenceDate
        }
    
        @IBAction func stopTimeAction(_ sender: Any) {
            endTime = Date().timeIntervalSinceReferenceDate
            print((endTime-startTime).time)
        }
    
    }
    

    extension TimeInterval {
        var time: String { .init(format: "%d:%02d:%02d.%03d", Int(self/3600),
                            Int((self/60).truncatingRemainder(dividingBy: 60)),
                            Int(truncatingRemainder(dividingBy: 60)),
                            Int((self*1000).truncatingRemainder(dividingBy: 1000))) }
    }
    
    0 讨论(0)
  • 2020-12-09 14:47

    NSDate is tied to the realtime clock on iOS and Mac devices, and has sub-millisecond accuracy.

    Use NSDate's timeIntervalSinceReferenceDate method to convert an NSDate (or the current time) to a double that is the number of seconds since January 1, 2001, including fractional seconds. Once you do that you're free to do math on the doubles that you get back.

    0 讨论(0)
提交回复
热议问题