在同步非隔离的上下文中调用主演员隔离实例方法XXX。

28

我正在尝试将异步 do/catch/defer 操作添加到 UIButton 上。然而,如果我只是在 defer 块中调用一个方法,我会收到“在同步非隔离上下文中调用主要角色隔离实例方法 XXX”的错误。我发现的解决方法是将其包装在另一个 Task 块中,如下所示。只想确认这是否是正确的方法?如果有人能解释一下这个错误消息实际上是什么意思,那就太好了。

@objc private func post(_ sender: UIButton) {
    Task {
        // defer { dismiss(animated: true) } -- Doesn't work
        defer { Task { await dismiss(animated: true) } }
        do {
            try await doSomethingAsync()
        } catch {
            print(error)
        }
    }
}

1
演员方法是异步的。它们是异步的,因为你不知道它们何时会运行 - 以防止多个方法同时在演员上运行。所以你基本上是在同步上下文中尝试运行异步方法,这是不可能的。这就像在普通函数中调用未标记为“async”的async方法一样。 - George
3
另一个解决方法是不使用“defer”。如果只想在成功时执行,则将其放在“doSomethingAsync”调用后面。如果想无论成功与否都执行,则将其放在“do-catch”块之后。 - Rob
1个回答

17

这是当前Swift版本中的一个错误,因为编译器无法识别defer块的全局actor上下文,有关此问题的讨论正在Swift论坛上进行,并且还提供了一个PR补丁,将在未来的Swift版本中解决此问题。目前,需要显式提供全局actor上下文以使代码编译:

defer { Task { @MainActor in dismiss(animated: true) } }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接