簡體   English   中英

DispatchTime.asyncafter的一致性

[英]Consistency of DispatchTime.asyncafter

在我的iPad應用程序中,我試圖讓tableView以預定間隔滾動。 為此,我創建了一段代碼,為每個滾動創建了一個閉合。 但是,關閉比我想要的要晚幾秒鍾執行。 這是一個簡化的游樂場,它例證了相同的問題。

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

// Intervals at which the delayed closures should run
var lengths: [Double] = [0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 
    12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0]
var times: [UInt64] = []

let dispatchStartTime = DispatchTime.now()

for index in 0 ..< lengths.count
{
    let delayNanoSeconds = Int(lengths[index] * 1_000_000_000)
    let dispatchLength = dispatchStartTime + .nanoseconds(delayNanoSeconds)
    times.append(dispatchLength.rawValue)

    DispatchQueue.main.asyncAfter(deadline: dispatchLength)
    {
        let delay = Double(DispatchTime.now().rawValue - times[index])
        print(delay/1_000_000_000)
    }
}

運行此程序后,我收到以下結果:(其他試驗以及應用程序中運行的代碼的結果相似)

0.01646185
0.190259978
0.000302805
0.59319351
0.732933723
0.938841374
1.08249717
1.326286228
8.6309e-05
0.00019526
0.000104861
2.19584049
0.196220036
2.000116042
0.000425943
0.000202886

我可以容忍50-100毫秒的錯誤。 但是,從結果中我們可以看到該錯誤可能大於2秒,並且它似乎隨着關閉時間/關閉量的增加而增加。 在我的應用程序中,此類間隔大約為100。 是否可以使用asyncAfter達到這種程度的特異性,還是采用諸如等待繁忙的一個線程之類的替代方案更好?

我已經實現了一個依賴於mach_wait_until的單線程版本。 這可能會導致准確性過高,但似乎對能源使用沒有任何嚴重的負面影響。

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

var timeInfo: mach_timebase_info = mach_timebase_info(numer: 0, denom: 0)
mach_timebase_info(&timeInfo)
// Intervals at which the delayed closures should run
var lengths: [Double] = [0.0, 2.0, 4.0,6.0,8.0,10.0,12.0,14.0,16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0, 42.0, 44.0, 46.0, 48.0, 50.0, 52.0, 54.0, 56.0, 58.0, 60.0, 62.0, 64.0, 66.0, 68.0, 70.0]

let startTime = mach_absolute_time()

DispatchQueue.global().async()
{
    for index in 0 ..< lengths.count
    {
        let delayTicks = UInt64(lengths[index] * 1_000_000_000) * UInt64(timeInfo.denom) / UInt64(timeInfo.numer)
        mach_wait_until(startTime + delayTicks)

        DispatchQueue.main.async()
        {
            // UI changes
        }
    }
}

mach_until_wait()似乎不能在操場上工作,但是我的應用程序中的代碼可以按預期工作,並且沒有明顯的延遲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM