mach_wait_until()iPad上的奇怪行为

时间:2018-05-05 01:20:23

标签: ios swift timer ios-simulator

我创建了一个简单的项目来测试mach_wait_until()的功能。此代码为我提供了1秒延迟精确度的准确打印输出。控制台打印输出在iOS模拟器和iPad Air 2上几乎完全相同且非常精确。但是,在我的iPad上有一个巨大的延迟,相同的1秒延迟大约需要100秒!并且为了增加它的怪异性,控制台中的打印输出表示它只需要1秒钟(具有极低的抖动和/或滞后)。

这怎么可能?在使用mach_wait_until()

时,我是否需要对物理iOS设备进行一些时序转换
class ViewController: UIViewController {

    override func viewDidLoad() {
      super.viewDidLoad()
      playNoteTest()
    }

    var start = mach_absolute_time()
    var end = mach_absolute_time()

    func playNoteTest() {
      let when = mach_absolute_time() + 1000000000

      self.start = mach_absolute_time()
      mach_wait_until(when)
      self.end = mach_absolute_time()
      let timeDelta = (self.end - self.start)
      let newTimeDelta = Double(timeDelta) / 1000000000.0
      print("Delta Time = \(newTimeDelta)")

      playNoteTest()
    }
}

1 个答案:

答案 0 :(得分:1)

mach_absolute_time单位取决于CPU。您需要乘以特定于设备的常量才能获得真实世界的单位。 Apple在此Tech Q&A中对此进行了讨论。

这是一些演示这个想法的游乐场代码:

import PlaygroundSupport
import Foundation

PlaygroundPage.current.needsIndefiniteExecution = true

class TimeBase {
    static let NANOS_PER_USEC: UInt64 = 1000
    static let NANOS_PER_MILLISEC: UInt64 = 1000 * NANOS_PER_USEC
    static let NANOS_PER_SEC: UInt64 = 1000 * NANOS_PER_MILLISEC

    static var timebaseInfo: mach_timebase_info! = {
        var tb = mach_timebase_info(numer: 0, denom: 0)
        let status = mach_timebase_info(&tb)
        if status == KERN_SUCCESS {
            return tb
        } else {
            return nil
        }
    }()

    static func toNanos(abs:UInt64) -> UInt64 {
        return (abs * UInt64(timebaseInfo.numer)) / UInt64(timebaseInfo.denom)      
    }

    static func toAbs(nanos:UInt64) -> UInt64 {
        return (nanos * UInt64(timebaseInfo.denom)) / UInt64(timebaseInfo.numer)
    }

}

let duration = TimeBase.toAbs(nanos: 10 * TimeBase.NANOS_PER_SEC)

DispatchQueue.global(qos: .userInitiated).async {

    print("Start")
    let start = mach_absolute_time()
    mach_wait_until(start+duration)
    let stop = mach_absolute_time()

    let elapsed = stop-start
    let elapsedNanos = TimeBase.toNanos(abs: elapsed)
    let elapsedSecs = elapsedNanos/TimeBase.NANOS_PER_SEC
    print("Elapsed nanoseconds = \(elapsedNanos)")
    print("Elapsed seconds = \(elapsedSecs)")

}