我在使异步函数在后台线程中运行时遇到问题(以防止阻塞主线程)。
下面是一个运行时间大约为 5 秒的方法。
据我所知,这似乎是使该功能async
并将其标记为await
在函数调用上就足够了。但它并没有按预期工作,并且用户界面仍然冻结。
EDIT由于据说 Swift 5.5 并发可以取代 DispatchQueue,因此我正在尝试找到一种仅使用 Async/Await 来实现此目的的方法。
EDIT_2我确实尝试删除 @MainActor 包装器,但它似乎仍然在主线程上运行。
NumberManager.swift
@MainActor class NumberManager: ObservableObject {
@Published var numbers: [Double]?
func generateNumbers() async {
var numbers = [Double]()
numbers = (1...10_000_000).map { _ in Double.random(in: -10...10) }
self.numbers = numbers
// takes about 5 seconds to run...
} }
内容视图
struct ContentView: View {
@StateObject private var numberManager = NumberManager()
var body: some View{
TabView{
VStack{
DetailView(text: isNumbersValid ? "First number is: \(numberManager.numbers![0])" : nil)
.onAppear() {
Task {
// Runs in the main thread, freezing up the UI until it completes.
await numberManager.generateNumbers()
}
}
}
.tabItem {
Label("One", systemImage: "list.dash")
}
Text("Hello")
.tabItem {
Label("Two", systemImage: "square.and.pencil")
}
}
}
var isNumbersValid: Bool{
numberManager.numbers != nil && numberManager.numbers?.count != 0
} }
我尝试过的...
我已经尝试了一些方法,但使其在后台运行的唯一方法是更改函数,如下所示。但我知道除非绝对必要,否则应该避免使用 Task.detached,而且我认为这不是正确的用例。
func generateNumbers() async {
Task.detached {
var numbers = [Double]()
numbers = (1...10_000_000).map { _ in Double.random(in: -10...10) }
await MainActor.run { [numbers] in
self.numbers = numbers
}
}