Каждая задача (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 запросов, управления настройками выполнения или отладки цепочек задач. Главное помнить, что это инструмент для легковесных данных, а не для сложных изменяемых объектов.
➡️ Подписаться на канал
Мобильный трудоголик