Blog - How ARC works — Automatic Reference Counting

Retain, release, weak/unowned, reference cycles, and what the compiler inserts for you in Objective-C and Swift.

Author
2code
Published
Tags
  • iOS
  • ARC
  • memory

ARC (Automatic Reference Counting) is the memory model in Objective-C and for classes in Swift: an object lives as long as something holds a strong reference to it.

Reference count

Each object has a count rr.

  • strong assignment: rr+1r \leftarrow r + 1
  • end of a strong reference’s lifetime: rr1r \leftarrow r - 1
  • when r=0r = 0deinit / dealloc, memory returns to the system

The compiler inserts retain / release (or equivalents) — it is not a heap-scanning garbage collector.

Strong, weak, unowned

  • strong (default) — owner; keeps the object alive.
  • weak — does not increment rr; becomes nil when the object is freed.
  • unowned — does not increment rr; you assert the object still lives (crash otherwise).

Retain cycles

Classic leak:

AstrongBstrongAA \xrightarrow{strong} B \xrightarrow{strong} A

Then rA1r_A \ge 1 and rB1r_B \ge 1 forever. Fix: one side weak (e.g. delegate), or unowned when lifetime is guaranteed.

In Swift closures:

someAsync { [weak self] in
  guard let self else { return }
  self.update()
}

Without [weak self], the closure often retains self → a cycle with its owner.

ARC ≠ GC

ARCGC
When it cleansimmediately at r=0r=0periodically / in pauses
Cyclesyou must break themusually detected
Predictabilitylow latencypossible stutter

That is why ARC fits iOS UI well: no surprise GC pauses, but cycles are your job.

Autorelease (ObjC)

Historically, an object can enter an autorelease pool and receive release later (e.g. end of the run loop). ARC still cooperates; in tight loops @autoreleasepool { ... } can prevent temporary-object buildup.

Takeaway

ARC is simple on the happy path and demanding on object graphs. Rule of thumb: one strong ownership path, break cycles with weak, especially for delegates and closures.

Back to blog

Let's talk about your project