在 Swift 5.5+ 中的后台线程上使用 JSONDecoder

问题描述 投票:0回答:2

以下 URL 会话是异步执行的。但是 JSON 解码步骤呢?这是在主线程上发生的吗?

func fetchFavorites() async throws -> [Int] {
    let url = URL(string: "https://hws.dev/user-favorites.json")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode([Int].self, from: data)
}
swift concurrency
2个回答
3
投票

如果函数与特定参与者隔离(无论是显式地隔离,还是作为与参与者隔离的类型的成员),它将在该参与者上运行。因此,如果隔离到主要参与者,那么

decode
将在主要参与者上运行(这导致它在主线程上运行)。

如果函数没有与任何特定的隔离,在 Swift 5.7 及更高版本中,它会在通用执行器上运行(即不是主线程),这要归功于 SE-0338)。简而言之,如果不与主要参与者隔离,它不会在主线程上运行。

如果此方法的类型与主要参与者隔离,则可以将其声明为

nonisolated
以使该功能脱离主要参与者。例如:

nonisolated func fetchFavorites() async throws -> [Int] {
    let url = URL(string: "https://hws.dev/user-favorites.json")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode([Int].self, from: data)
}

1
投票

您正在从异步

decode(...)
函数中调用
fetchFavorites()
。这意味着其中的所有代码都在 Swift 运行时认为最有效的任何线程上运行。在实践中,这可能不会成为主线程,但理论上它有时可能是。

© www.soinside.com 2019 - 2024. All rights reserved.