SwiftQA Random

How does ARC interact with Swift concurrency?

The baseline: ARC doesn’t know about concurrency, and never needed to

ARC’s job is unchanged: retain on copy/capture, release on scope exit, deinit at zero.

1. Retain/release counts must themselves be thread-safe

Swift’s ARC implementation uses atomic operations for retain/release — this was true even in the GCD era, so concurrency didn’t introduce this cost.

2. Sendable is what prevents ARC-safe-but-logically-unsafe sharing

ARC keeps an object from being deallocated prematurely even if shared across threads — but says nothing about the object’s contents. Sendable closes that gap.

3. Actors change where ARC traffic can happen, not whether

Cross-actor calls still retain/release arguments and results as they cross.

4. Suspension points and retain/release lifetime

A value held via a strong reference across an await keeps its reference count elevated — ARC guarantees memory safety across the suspension, but says nothing about logical staleness (reentrancy).

5. Task closures and captured references

class Model { var data: [Int] = [] }
func launch(_ model: Model) {
    Task {
        model.data.append(1)  // ARC: fine. Sendable checker: ❌ unless Model is Sendable
    }
}

ARC is the mechanism that keeps memory valid; Sendable/isolation is the separate layer deciding whether sharing that memory is logically safe.

6. Weak/unowned references and actor-isolated closures

[weak self] in Task { } bodies applies identically to any long-lived closure context.

7. Global actors and deinit

deinit is inherently non-isolated and cannot await or safely touch other actor-isolated state.

Summary

LayerGuaranteesDoes NOT guarantee
ARC (atomic retain/release)Object won’t be freed while referenced, even across threadsContents are safe from concurrent mutation
Sendable/isolation checkingValues crossing domains have no unsynchronized shared mutable stateLogical correctness
Actor isolationOne task touches actor-isolated state at a timeState unchanged across await (reentrancy)

One-liner if pressed: “ARC has always used atomic retain/release since objects could be shared across threads even before structured concurrency — so ARC alone keeps memory valid, but says nothing about whether an object’s contents are safe to touch concurrently; that’s the gap Sendable and actor isolation close on top of ARC.”