当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Swift TaskLocal用法及代码示例

TaskLocal

定义 task-local 值键的属性包装器。

声明

@propertyWrapper final class TaskLocal<Value> where Value : Sendable

概述

task-local 值是可以在 Task 的上下文中绑定和读取的值。它隐含在任务中,可由任务创建的任何子任务(例如TaskGroup 或async let 创建的任务)访问。

Task-local 声明

任务局部变量必须声明为静态属性(或全局属性,一旦属性包装器支持这些),如下所示:


enum TracingExample {
    @TaskLocal
    static let traceID: TraceID?
}

默认值

可选类型的任务本地值默认为 nil 。可以定义 not-optional task-local 值,然后必须定义显式默认值。

每当从以下任一上下文中读取 task-local 时都会返回默认值: 没有可用于读取值的任务(例如,同步函数,在其调用堆栈中没有任何异步函数的情况下调用),

读取 task-local 值

读取任务本地值很简单,看起来与读取普通静态属性的 as-if 相同:


guard let traceID = TracingExample.traceID else {
  print("no trace id")
  return
}
print(traceID)

可以从异步或同步函数执行 task-local 值读取。在异步函数中,由于始终保证 “current” 任务存在,这将在任务本地上下文中执行查找。

从同步函数的上下文中进行的查找,而不是从异步函数 (!) 调用,将立即返回 task-local 的默认值。

绑定 task-local 值

任务本地值不能直接为set,而必须使用作用域$traceID.withValue() { ... } 操作绑定。该值仅在该范围内绑定,并且可用于在该范围内创建的任何子任务。

分离的任务不继承 task-local 值,但是使用 Task { ... } 初始化程序创建的任务通过将它们复制到新的异步任务来继承 task-locals,即使它是 un-structured 任务。

例子


@TaskLocal
static var traceID: TraceID?


print("traceID: \(traceID)") // traceID: nil


$traceID.withValue(1234) { // bind the value
  print("traceID: \(traceID)") // traceID: 1234
  call() // traceID: 1234


  Task { // unstructured tasks do inherit task locals by copying
    call() // traceID: 1234
  }


  Task.detached { // detached tasks do not inherit task-local values
    call() // traceID: nil
  }
}


func call() {
  print("traceID: \(traceID)") // 1234
}

此类型必须是class,因此它具有稳定的标识,用作任务本地存储中查找的键值。

可用版本

iOS 13.0+, iPadOS 13.0+, macOS 10.15+, Mac Catalyst 13.0+, tvOS 13.0+, watchOS 6.0+

相关用法


注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 TaskLocal。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。