[SC] 在 SwiftUI 中执行 Tasks
Source: Dev.to
示例搜索与 .task 有什么关系?
我们重新使用 search(_ query: String) 示例,其中在 500 ms 的防抖后过滤条目。在这个示例中,需要保存一个 Task 的引用,以便后续取消它,放在 ArticleSearcher 类(它是 Observable)中。稍后,在视图中通过 onChange(of:) 调用 search(_:) 方法。
@MainActor
@Observable
final class ArticleSearcher {
private static let articleTitlesDatabase = [
"Article one",
"Article two",
"Article three",
]
var searchResults: [String] = ArticleSearcher.articleTitlesDatabase
private var currentSearchTask: Task?
func search(_ query: String) {
currentSearchTask?.cancel()
currentSearchTask = Task {
do {
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
searchResults = Self.articleTitlesDatabase.filter {
$0.lowercased().contains(query.lowercased())
}
} catch {
print("Search was cancelled!")
}
}
}
}.task 修饰符是如何工作的?
SwiftUI 允许通过 .task() 将一个 Task 挂钩到视图的生命周期。任务会在视图出现之前调度,在视图消失时自动取消。现在不再需要使用 Task { } 包裹要触发的任务,只需把方法签名改为 async 即可。
search(_ query: String) 的最终实现
func search(_ query: String) async {
do {
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
} catch {
print("Search was cancelled!")
}
}.task 中的 id: 参数有什么作用?
.task() 会在视图出现之前启动任务。当 id: 参数的值变化时,之前的任务会自动被取消,并重新启动一个新任务。
.task 中的 .priority 参数有什么作用?
由于 Swift Concurrency 使用的是协作式线程池,我们可以通过改变优先级来影响任务相对于其他任务的行为。SwiftUI 默认使用 userInitiated,因此通常可以将优先级调低为 utility(中等)或 background(低)。