---
title: "Captures in a `@Sendable` closure (SendableClosureCaptures)"
framework: swift-compiler
role: article
role_heading: Article
path: swift-compiler/documentation/diagnostics/sendable-closure-captures
---

# Captures in a `@Sendable` closure (SendableClosureCaptures)

## Overview

Overview @Sendable closures can be called multiple times concurrently, so any captured values must also be safe to access concurrently. To prevent data races, the compiler prevents capturing mutable values in a @Sendable closure. For example: func callConcurrently(   _ closure: @escaping @Sendable () -> Void ) { ... }

func capture() {   var result = 0   result += 1

callConcurrently {     print(result)   } } The compiler diagnoses the capture of result in a @Sendable closure: |   callConcurrently { |     print(result) |           `- error: reference to captured var 'result' in concurrently-executing code |   } | } Because the closure is marked @Sendable, the implementation of callConcurrently can call closure multiple times concurrently. For example, multiple child tasks within a task group can call closure concurrently: func callConcurrently(   _ closure: @escaping @Sendable () -> Void ) {   Task {     await withDiscardingTaskGroup { group in       for _ in 0..<10 {         group.addTask {           closure()         }       }     }   } } If the type of the capture is Sendable and the closure only needs the value of the variable at the point of capture, resolve the error by explicitly capturing the variable by value in the closure’s capture list: func capture() {   var result = 0   result += 1

callConcurrently { [result] in     print(result)   } } This strategy does not apply to captures with non-Sendable type. Consider the following example: class MyModel {   func log() { ... } }

func capture(model: MyModel) async {   callConcurrently {     model.log()   } } The compiler diagnoses the capture of model in a @Sendable closure: | func capture(model: MyModel) async { |   callConcurrently { |     model.log() |     `- error: capture of 'model' with non-Sendable type 'MyModel' in a '@Sendable' closure |   } | } If a type with mutable state can be referenced concurrently, but all access to mutable state happens on the main actor, isolate the type to the main actor and mark the methods that don’t access mutable state as nonisolated: @MainActor class MyModel {   nonisolated func log() { ... } }

func capture(model: MyModel) async {   callConcurrently {     model.log()   } } The compiler will guarantee that the implementation of log does not access any main actor state. If you manually ensure data-race safety, such as by using an external synchronization mechanism, you can use nonisolated(unsafe) to opt out of concurrency checking: class MyModel {   func log() { ... } }

func capture(model: MyModel) async {   nonisolated(unsafe) let model = model   callConcurrently {     model.log()   } }

## See Also

- [@dynamicCallable implementation requirements (DynamicCallable)](swift-compiler/documentation/diagnostics/dynamic-callable-requirements.md)
- [Add @preconcurrency import (AddPreconcurrencyImport)](swift-compiler/documentation/diagnostics/add-preconcurrency-import.md)
- [Always enabled availability domains (AlwaysAvailableDomain)](swift-compiler/documentation/diagnostics/always-available-domain.md)
- [Argument matching for trailing closures (TrailingClosureMatching)](swift-compiler/documentation/diagnostics/trailing-closure-matching.md)
- [Calling a mutating async actor-isolated method (ActorIsolatedMutatingAsync)](swift-compiler/documentation/diagnostics/actor-isolated-mutating-async.md)
- [Calling an actor-isolated method from a synchronous nonisolated context (ActorIsolatedCall)](swift-compiler/documentation/diagnostics/actor-isolated-call.md)
- [Compilation caching (CompilationCaching)](swift-compiler/documentation/diagnostics/compilation-caching.md)
- [Conforming to `StringInterpolationProtocol` (StringInterpolationConformance)](swift-compiler/documentation/diagnostics/string-interpolation-conformance.md)
- [Conversion from `@isolated(any)` function type to synchronous function type (ConversionFromIsolatedAnyToSynchronous)](swift-compiler/documentation/diagnostics/conversion-from-isolated-any-to-synchronous.md)
- [Cross-isolation data race (RegionIsolationCrossIsolationDataRace)](swift-compiler/documentation/diagnostics/region-isolation-cross-isolation-data-race.md)
- [Deprecated declaration warnings (DeprecatedDeclaration)](swift-compiler/documentation/diagnostics/deprecated-declaration.md)
- [Deprecated implementation-only imports (ImplementationOnlyDeprecated)](swift-compiler/documentation/diagnostics/implementation-only-deprecated.md)
- [Dynamic exclusivity (DynamicExclusivity)](swift-compiler/documentation/diagnostics/dynamic-exclusivity.md)
- [Embedded Swift language restrictions (EmbeddedRestrictions)](swift-compiler/documentation/diagnostics/embedded-restrictions.md)
- [Existential Types and Performance (ExistentialType)](swift-compiler/documentation/diagnostics/existential-type.md)
