當應用程式在 Swift 中使用新的異步/等待并發模型進入后臺時,我正在努力執行代碼。這是我的代碼:
@main
struct TestApp: App {
@Environment(\.scenePhase) var scenePhase
var body: some View {
ContentView()
}
.onChange(of: scenePhase) {
if $0 == .background {
Task {
var bgTaskId: UIBackgroundTaskIdentifier = .invalid
bgTaskId = UIApplication.shared.beginBackgroundTask {
print("ran out of time")
UIApplication.shared.endBackgroundTask(bgTaskId)
bgTaskId = .invalid
}
await UserManager.user.save() // func save() async {...}
print("executes this immediately")
UIApplication.shared.endBackgroundTask(bgTaskId)
bgTaskId = .invalid
}
}
}
}
struct User {
func save() async {
print("Never calls this...")
await Task.sleep(nanoseconds: 3_000_000_000)
}
}
所以我從來沒有看到 print 呼叫,save()但我確實看到了Task.initof中的所有 print 呼叫onChange()。是否有一些關于 async/await 如何執行的東西使這不可能,或者我在這里遺漏了什么?
我能夠執行后臺獲取 pre-async/await 方式,DispatchQueue.global().async{...}以及隨后的呼叫.beingBackgroundTask和呼叫endBackgroundTask中的onChange()呼叫,所以我知道它是async/await專門針對的。謝謝!
uj5u.com熱心網友回復:
這種模式效果很好。但是這些print陳述讓我懷疑您一定是在嘗試在 Xcode 除錯器控制臺中觀看此內容。但是在測驗后臺生命周期事件時,您不希望附加到 Xcode 除錯器,因為這會人為地改變應用程式生命周期。
這就引出了一個問題,即如何在未連接到 Xcode 的情況下查看日志記錄訊息。就個人而言,我使用統一的日志系統,即
一些不相??關的觀察:
我的代碼片段使用
guard早期退出,以避免大括號。我有意識地避免在異步行程中啟動后臺任務。我們希望避免應用程式掛起和創建后臺任務之間的競爭。所以我在啟動異步行程之前創建了后臺任務。
.invalid在嘗試結束任務之前,我總是確保后臺任務識別符號尚未存在。您希望避免超時和正常終止之間的競爭。為您的后臺任務提供名稱可能是謹慎的做法。
這四點對手頭的問題都不是非常關鍵,但我想簡單地展示一些最佳實踐: 關鍵觀察是(a)在 Xcode 之外進行測驗;(b) 使用統一的日志系統,以便您可以監控進度。還有其他方法可以監控進度,但這可能是最簡單的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/508502.html
下一篇:反應本機變數不在函式內部更新
