在不支持并发 swift ios Xcode async/await 的函数中调用“异步”

dre*_*ter 5 macos xcode ios async-await swift

我正在尝试在 Swift 5.5 中使用 async/await。我有我的异步函数,但是每当我尝试调用它时,我都会收到此错误:

不支持并发的函数中的“异步”调用

这是代码示例:

class TryThis {
    func getSomethingLater(_ number: Double) async -> String {
        // test - sleep for 3 seconds, then return
        Thread.sleep(forTimeInterval: 3)
        return String(format: ">>>%8.2f<<<", number)
    }
}

let tryThis = TryThis()

let result = await tryThis.getSomethingLater(3.141592653589793238462)
print("result: \(result)")
Run Code Online (Sandbox Code Playgroud)

这个有什么解决办法??

Sup*_*tar 11

当从非代码调用async代码(包括actor字段)时async,您必须将其包装在Task

\n
Task {\n    let result = await tryThis.getSomethingLater(3.141592653589793238462)\n    print("result: \\(result)")\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果您需要它来转义异步上下文,您可以使用传统的回调:

\n
func awaitedResult(callback: @escaping (String) -> Void) {\n    Task {\n        let result = await tryThis.getSomethingLater(3.141592653589793238462)\n        callback(result)\n    }\n}\n\nawaitedResult { result in\n    print("result: \\(result)")\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Sundell 的 Swift还提供了一些涉及合并的替代方案

\n
\n

进一步阅读:并发 \xe2\x80\x94 Swift 编程语言 (Swift 5.5)

\n


dre*_*ter 7

这里的答案是必须从异步上下文调用“await getSomethingLater”。从字面上看,这意味着改变这一点:

let result = await tryThis.getSomethingLater(3.141592653589793238462)
print("result: \(result)")
Run Code Online (Sandbox Code Playgroud)

进入这个:

Task {
    let result = await tryThis.getSomethingLater(3.141592653589793238462)
    print("result: \(result)")
}
Run Code Online (Sandbox Code Playgroud)

所以整个事情变成了:

class TryThis {
    func getSomethingLater(_ number: Double) async -> String {
        // test - sleep for 3 seconds, then return
        Thread.sleep(forTimeInterval: 3)
        return String(format: ">>>%8.2f<<<", number)
    }
}

let tryThis = TryThis()

Task {
    let result = await tryThis.getSomethingLater(3.141592653589793238462)
    print("result: \(result)")
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

结果:>>> 3.14<<<

来自 WWDC21的Meet 同步/等待 Swift视频中有很好的信息。

  • 我收到警告“async(priority:operation:)”已弃用:“async”已被“Task.init”取代,并将很快被删除。我认为这意味着这个答案不应再被接受。 (2认同)
  • 请注意:您可以使用“.pi”而不是文字:“tryThis.getSomethingLater(.pi)” (2认同)