Logo for tanaschita.com

Understanding Task and Task.detached in Swift concurrency

Learn the what the differences are between Task and Task.detached in Swift.

02 Nov 2025 · 6 min read

When we explored structured and unstructured tasks, we saw a small example of using Task {} vs. Task.detached {}.

In this article, we'll go a bit deeper and look at how the two differ, and when it makes sense to use each.

Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE

Staying in context with Task

When we create a regular Task, it inherits context from where it's started.

That means:

  • If we’re inside an actor, the new task runs on that actor.
  • If the parent task has a certain priority or is cancelled, that state is inherited.

For example:

actor DataService {
func refresh() {
Task {
await updateCache()
}
}
}

Here, updateCache() runs inside the actor. We don't need to think about isolation or thread safety, Swift takes care of that.

Creating an independent task with Task.detached

Task.detached starts a completely independent task. It doesn't inherit any context: not actor isolation, not priority, not cancellation.

In some cases, we can offload work from an actor so that it stays responsive. Actors process one piece of work at a time, so if we want to perform longer operations that don't depend on the actor's state, we can run them outside the actor's executor:

actor UserService {
private let secureStore: SecureStore
func clear() {
Task.detached { [secureStore] in
await secureStore.clearTokens()
}
}
}

Here, the actor becomes available immediately after starting the detached task.

However, this only works if secureStore is safe to call from outside the actor, for example, if they are actors themselves or thread-safe.

When detaching doesn't help

The example above works because the detached task doesn't touch the actor's state. But if we try to access it, we lose the benefit:

actor DataService {
func refresh() {
Task.detached { [weak self] in
guard let self else { return }
await self.updateCache()
}
}
private func updateCache() async { ... }
}

This compiles, but it's effectively the same as using a regular Task. The detached task runs independently, then immediately hops back into the actor to do its work. So there's no real advantage here, we could have used a regular Task instead.

Also, it's a common misconception that Task.detached is necessary to make a task "keep running". That's not the case. Once a normal task is created outside structured concurrency, it already runs independently. A detached task doesn’t change that behavior. For example:

class DataService {
func startWork() {
Task {
await doLongRunningWork()
}
}
}

This task will continue until it completes or is cancelled explicitly. Replacing it with Task.detached changes nothing in practice.

So if our goal is simply to start background work that finishes on its own, a normal Task is usually enough.

Sponsorship logo
Preparing for a technical iOS job interview
Preparing for a technical iOS Job Interview with over 300 questions & answers. Covering Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, iOS File System, Core Data, Concurrency with async/await, Security, Automated Testing, Dependency Management, AI & Machine Learning and more.
LEARN MORE
Sponsorship logo
Architecture & Design Patterns for iOS
This book is a practical guide to essential architectural principles and design patterns for iOS development. It covers strategies for building maintainable apps with Swift and SwiftUI, including dependency injection, navigation, common patterns, and modularization.
LEARN MORE
Sponsorship logo
Become a sponsor of tanaschita.com
By publishing an article on different iOS topics every week, tanaschita.com is constantly growing in the developer community and may provide a great audience for you as a sponsor.
CLICK TO LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

async/await

concurrency

swift

Understanding Sendable in Swift

Learn what Sendable means in Swift concurrency and how it helps prevent data races.

06 Jul 2026 · 8 min read

Latest articles and tips

© 2026 tanaschita.com

Privacy policy

Impressum