Добавить объявление

Task Local: Как передавать данные между задачами в Swift

Каждая задача (Task) в Swift может иметь свой собственный контекст - локальные данные, доступные ей и ее дочерним задачам. Это похоже на ThreadLocal, но для асинхронных задач.

Как это работает:


  • @TaskLocal: проперти-враппер, который позволяет шарить данные между задачами.

  • withValue: задаёт значение на время выполнения блока кода.

  • Наследование: дочерние задачи (async let, TaskGroup) получают копию контекста родителя.

Пример:


@TaskLocal static var requestID: String?

func fetchData() async {
print("Request ID:", requestID ?? "unknown") // Доступ к контексту
}

Task {
await $requestID.withValue("123") {
await fetchData() // Выведет "123"
}

await fetchData() // Выведет "unknown" так как контекст сброшен
}

Что под капотом:


  • Хранилище: словарь стеков (каждый ключ - свой стек значений).

  • withValue: пушит значение в стек, defer - удаляет после выполнения.

  • Sendable-типы: гарантируют потокобезопасность.

Ограничения:


  • Не для больших данных: только для легковесного контекста (ID, флаги).

  • Изменяемые объекты: если передаёте класс, изменения будут видны во всех задачах.

Вывод:


Task Local отлично подходит для передачи контекстных данных в асинхронных операциях - например, для логирования ID запросов, управления настройками выполнения или отладки цепочек задач. Главное помнить, что это инструмент для легковесных данных, а не для сложных изменяемых объектов.
21.08.2025 36 430