4

在这种情况下,异步函数读取文件并返回解析的内容。

在我看来,我想从主线程中加载内容,然后在完成后更新视图。

我在各个地方都使用过这种模式,并注意到在某些情况下异步调用在主线程上(通过调试),而在其他情况下它在Thread 4 Queue : com.apple.root.user-initiated-qos.cooperative (concurrent)线程上

例如:

struct MyView: View {
  @State var data = "some data"
  var body: some View {
    Button("refresh") {
    // when the button is pressed refresh it
            Task {
                await refresh()
            }
        }.task {
    // when the view appears
            await refresh()
        }
     Text("the data is \(data)") // write the data which was refreshed async
   }


  }
  func refresh() async {
        do {
            let res = try await anotherAyncFunction()
            data = res // this is presumably wrong and off the main thread - obviously might not be correct but leave here for debug as well
        } catch {
            print("got error \(error)")
        }
    }

我使用类似的模式创建了几个不同的视图(.task块调用async函数)

在某些情况下,函数长时间运行(从磁盘读取)并且发生在主线程上

4

2 回答 2

3

更改Task {Task.detached {

来自Swift 语言指南

要创建在当前参与者上运行的非结构化任务,请调用Task.init(priority:operation:)初始化程序。要创建不属于当前参与者的非结构化任务,更具体地称为分离任务,请调用Task.detached(priority:operation:)类方法。

当您调用Task.init时,异步代码在当前参与者上运行,在此上下文中,该参与者是主要参与者。这会导致阻塞主线程。

通过调用Task.detached,您允许异步工作发生在主线程之外。

于 2021-11-13T05:24:01.740 回答
0

使用 Swift 结构化并发,在后台线程上运行代码,使用分离任务或(更好)演员。

于 2021-10-28T12:28:00.873 回答