簡體   English   中英

如何在指定日期/時間撥打 Swift function

[英]How to call Swift function at specified date/time

在 iOS 上的 Swift 中以精確(1 秒內)日期/時間觸發功能/塊的最佳方法是什么?

我試過將TimerinitfireAt一起使用,但我發現精度通常會降低幾秒鍾。 將計時器精度設置為 0.5 之類的值並沒有產生更好的結果。

我也嘗試過將 GCD 與DispatchQueue.main.asyncAfter(.now() + someDelay)一起使用,並且在我的測試中這也經常關閉幾秒鍾。

我已經確定的是創建一個每秒觸發一次的計時器,然后我檢查當前日期/時間是否已經超過我想要的值,然后我手動觸發我的代碼。 似乎有更好的方法 go 關於這個,但我沒有想法。 謝謝!

如果你用帶有makeTimerSource標志的.strict創建一個 GCD 計時器,它會選擇退出計時器合並:

系統會盡最大努力觀察計時器的指定leeway值,即使該值小於默認余地。

例如:

var timer: DispatchSourceTimer?

func startTimer(in interval: DispatchTimeInterval, block: @escaping () -> Void) {
    timer = DispatchSource.makeTimerSource(flags: .strict, queue: .main)
    timer?.setEventHandler(handler: block)
    timer?.schedule(deadline: .now() + interval, leeway: .milliseconds(500))
    timer?.activate()
}

然后:

startTimer(in: .seconds(240)) { [weak self] in
    self?.foo()
}

請注意,與Timer不同,它由您安排它的RunLoop保留,您必須保留自己對 GCD 計時器的強引用,如上所示。 您可能會使Timer屬性weak (以便在RunLoop釋放它們時釋放它們),但您需要對 GCD 計時器的強引用。

一些注意事項:

  • 注意使用[weak self]捕獲列表。 您通常希望避免強引用循環(尤其是在計時器是重復計時器的情況下)。

  • 只有在絕對需要時才應使用此模式,因為您選擇退出計時器合並提供的節能功能。 我希望這比重復計時器方法更節能,但比讓操作系統使用其自由裁量權來合並其計時器更節能。

  • 此模式假定調度它的隊列未被阻塞。 顯然,我們從不阻塞主線程,但您始終可以考慮使用自己的目標隊列。

  • 為了未來的讀者,這種模式顯然適用於應用程序實際運行時。 如果應用程序被掛起,計時器將無法觸發。 如果您希望即使應用程序當前未運行也能在指定時間通知用戶,您可以使用本地計划的用戶通知

暫無
暫無

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

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