在某些情况下,当从任务运行时,swift 异步函数正在主线程上运行

Avn*_*arr 6 swift swift5 swiftui swift-concurrency

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

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

我在不同的地方使用过这种模式,并注意到在某些情况下,异步调用是在主线程上(通过调试),而在其他情况下,它是在线程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)")
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

Joh*_* M. 6

改成。Task {Task.detached {

\n

来自Swift 语言指南

\n
\n

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

\n
\n

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

\n

通过调用Task.detached,您可以允许异步工作在主线程之外进行。

\n

  • 不起作用,我的“任务”已分离,但它位于主线程上。 (10认同)

mat*_*att 3

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