2025-02-08 12:19:33
,某些文章具有时效性,若有错误或已失效,请在下方留言。Swift tasks can have a priority attached to them, such as .high
or .background
, but the priority can also be nil
if no specific priority was assigned. This priority can be used by the system to determine which task should be executed next, but this isn’t guaranteed – think of it as a suggestion rather than a rule.
Swift 任务可以附加一个优先级,例如 .high
或 .background
,但如果未分配特定优先级,则优先级也可以为 nil
。系统可以使用此优先级来确定接下来应该执行哪个任务,但这并不能保证 – 将其视为建议而不是规则。
Creating a task with a priority looks like this:
创建具有优先级的任务如下所示:
func fetchData() async {
let downloadTask = Task(priority: .high) {
let url = URL(string: "https://hws.dev/chapter.txt")!
let (data, _) = try await URLSession.shared.data(from: url)
return String(decoding: data, as: UTF8.self)
}
do {
let text = try await downloadTask.value
print(text)
} catch {
print(error.localizedDescription)
}
}
await fetchData()
Although you can directly assign a priority to a task when it’s created, if you don’t then Swift will follow three rules for deciding the priority automatically:
虽然您 可以 在任务创建时直接为其分配优先级,但如果您不这样做,那么 Swift 将遵循三个规则来自动决定优先级:
- If the task was created from another task, the child task will inherit the priority of the parent task.
如果任务是从另一个任务创建的,则子任务将继承父任务的优先级。 - If the new task was created directly from the main thread as opposed to a task, it’s automatically assigned the highest priority of
.high
.
如果新任务是直接从主线程而不是任务创建的,则会自动为其分配最高优先级.high
。 - If the new task wasn’t made by another task or the main thread, Swift will try to query the priority of the thread or give it a
nil
priority.
如果新任务不是由另一个任务或主线程创建的,Swift 将尝试查询线程的优先级或给它一个nil
优先级。
This means not specifying an exact priority is often a good idea because Swift will do The Right Thing.
这意味着不指定确切的优先级通常是一个好主意,因为 Swift 会做正确的事情。
However, like I said you can also specify an exact priority from one of the following:
但是,正如我所说,您也可以从以下选项之一中指定确切的优先级:
- The highest priority is
.high
, which is synonymous with the old.userInitiated
priority from Grand Central Dispatch (GCD). As the name implies, this should be used only for tasks that the user specifically started and is actively waiting for.
最高优先级是.high
,它与 Grand Central Dispatch (GCD) 中的旧.userInitiated
优先级同义。顾名思义,这应该仅用于用户专门启动并正在积极等待的任务。 - Next highest is
.medium
, which is a great choice for most of your tasks that the user isn’t actively waiting for.
其次是.medium
,对于用户没有主动等待的大多数任务来说,这是一个不错的选择。 - Next is
.low
, which is synonymous with the old.utility
priority from GCD. This is the best choice for anything long enough to require a progress bar to be displayed, such as copying files or importing data.
接下来是.low
,它与 GCD 中的旧.utility
优先级同义。对于需要显示进度条的任何时间足够长的任何作(例如复制文件或导入数据),这是最佳选择。 - The lowest priority is
.background
, which is for any work the user can’t see, such as building a search index. This could in theory take hours to complete.
最低优先级是.background
,它适用于用户看不到的任何工作,例如构建搜索索引。理论上,这可能需要数小时才能完成。
Like I said, priority inheritance helps get us a sensible priority by default, particularly when creating tasks in response to a user interface action.
就像我说的,优先级继承有助于我们在默认情况下获得合理的优先级,尤其是在创建响应用户界面作的任务时。
For example, we could build a simple SwiftUI app using a single task, and we don’t need to provide a specific priority – it will automatically run as high priority because it was started from our UI:
例如,我们可以使用单个任务构建一个简单的 SwiftUI 应用程序,并且不需要提供特定的优先级 – 它将自动以高优先级运行,因为它是从我们的 UI 启动的:
struct ContentView: View {
@State private var jokeText = ""
var body: some View {
VStack {
Text(jokeText)
Button("Fetch new joke", action: fetchJoke)
}
}
func fetchJoke() {
Task {
let url = URL(string: "https://icanhazdadjoke.com")!
var request = URLRequest(url: url)
request.setValue("Swift Concurrency by Example", forHTTPHeaderField: "User-Agent")
request.setValue("text/plain", forHTTPHeaderField: "Accept")
let (data, _) = try await URLSession.shared.data(for: request)
if let jokeString = String(data: data, encoding: .utf8) {
jokeText = jokeString
} else {
jokeText = "Load failed."
}
}
}
}
Any task can query its current priority using Task.currentPriority
, but this works from anywhere – if it’s called in a function that is not currently part of a task, Swift will query the system for an answer or send back .medium
.
任何任务都可以使用 Task.currentPriority
查询其当前优先级,但这可以在任何地方进行 – 如果在当前不属于任务的函数中调用它,Swift 将查询系统以获取答案或发回 .medium
。