[SC] 在 SwiftUI 中执行 Tasks

发布: (2026年3月14日 GMT+8 22:43)
3 分钟阅读
原文: Dev.to

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(低)。

参考文献

0 浏览
Back to Blog

相关文章

阅读更多 »

[SC] 可发送

在 GCD 与 Swift Concurrency 之间在线程间传递值有什么区别?和 GCD 一样,在 Swift Concurrency 中也需要传递数据……