我正在使用下面的代码来使用mach_wait_until()等待指定的时间段(以纳秒为单位)。

private func startTimerAndResume(){

    let idealNanos: UInt64 = 1250130250 //1.25 seconds

    let deadline = CFAbsoluteTime(mach_absolute_time() + (timeUnitsFor(nanos: idealNanos))/100)

    let x = mach_absolute_time()

    mach_wait_until(UInt64(deadline))

    let y = mach_absolute_time()


    var timeBaseInfo = mach_timebase_info_data_t()
    mach_timebase_info(&timeBaseInfo)
    let elapsedNanos = (y - x) * UInt64(timeBaseInfo.numer) / UInt64(timeBaseInfo.denom);

    print("deadline (aka mach-abs-time + timeUnitsFor()) = \(deadline)")
    print("(mach-abs-y)-(mach-abs-x) = \(y-x)")
    print("error in time units = \((y-x)-(timeUnitsFor(nanos: idealNanos))/100)")
    print("elapsed nanos actual = ", elapsedNanos)
    print("elapsed nanos ideal = ", idealNanos)
    print("error in nanoseconds = \(elapsedNanos - idealNanos)")
}


private func timeUnitsFor(nanos: UInt64)-> UInt64{

    var timeBaseInfo = mach_timebase_info_data_t()
    mach_timebase_info(&timeBaseInfo)

    let numer: UInt64 = UInt64(timeBaseInfo.numer)
    let denom: UInt64 = UInt64(timeBaseInfo.denom)

    //elapsed time in nanoseconds = timUnits * (numer / denom) ... therefore ->
    let timeUnits: UInt64 = (nanos*denom/numer)*(UInt64(100))//multiply by 100 to preserve decimal before truncation caused by UInt64() conversion
    print("timeUnits = \((timeUnits)/100) for target nanos \(nanos) when numer = \(numer) and denom = \(denom)")
    return timeUnits
}

当我在实际的iPhone设备上运行此程序时,错误通常在1毫秒左右,并且输出如下:
timeUnits = 30003126 for target nanos 1250130250 when numer = 125 and denom = 3deadline (aka mach-abs-time + timeUnitsFor()) = 4025277628801.0(mach-abs-y)-(mach-abs-x) = 30027213timeUnits = 30003126 for target nanos 1250130250 when numer = 125 and denom = 3error in time units = 24087elapsed nanos actual = 1251133875elapsed nanos ideal = 1250130250error in nanoseconds = 1003625
但是,当我在模拟器上运行此计时器时,它始终延迟70到74毫秒,这是输出:
timeUnits = 1250130250 for target nanos 1250130250 when numer = 1 and denom = 1deadline (aka mach-abs-time + timeUnitsFor()) = 691695760744956.0(mach-abs-y)-(mach-abs-x) = 1322288698timeUnits = 1250130250 for target nanos 1250130250 when numer = 1 and denom = 1error in time units = 72158448elapsed nanos actual = 1322288698elapsed nanos ideal = 1250130250error in nanoseconds = 72158448
我想知道为什么模拟器每次都晚70到74毫秒。我在进行纳秒和马赫时间单位之间的转换是错误的吗?谢谢

最佳答案

该模拟器不是用于精确时钟测试的精确时钟手臂仿真器。它是面向Intel的iOS版本,并与其他主机OS共享内核。

您的计时器可能不在模拟器中,而在模拟器中已合并。根据您的主机配置和运行时版本,模拟器进程可能正在Utility QoS层上运行。

因此,您看到时间差异的原因是由于以下一个或多个原因:

  • 英特尔vs ARM
  • 不同的内核版本(主机内核与配对的iOS内核版本)
  • 与系统上的其他进程争用
  • 由于不同的QoS层导致计时器合并

  • 您不应该依赖于在特定窗口内重新获得控制权,因为这不在API合同中。时间到了之后,您将被安排在某个时间点。

    关于ios - 在模拟器上运行时,为什么mach_wait_until会迟到?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40858224/

    10-10 10:34