Autorelease pools today

Memory & ARC Mid-level Swift 5.0+ iOS 17+ Reviewed By Alok Singh

Pick the fix

Resizing 10,000 photos in a loop uses gigabytes of memory until the loop ends. Best fix?

Options
Hint 1 of 1

When are autoreleased objects freed?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Wrap the loop body in autoreleasepool { }

Correct. Each iteration's autoreleased images are freed right away.

Why not the others?
  • B Dispatch each iteration with DispatchQueue.main.async. That moves work to the UI thread and doesn't bound memory.
  • C Set the image variable to nil at the end of each iteration. The autoreleased objects are still waiting for the pool to drain.
  • D Lower the JPEG quality. Smaller files don't change how long autoreleased objects live.

30-second answer

Some Objective-C APIs return autoreleased objects that are freed only when the current autorelease pool drains, usually at the end of a run-loop turn. In a tight loop creating many such objects, such as images or Foundation strings, memory spikes until the loop ends. Wrapping the loop body in autoreleasepool { } frees them each iteration.

Practise saying it · 30 s. No recording, just a timer

Explain when autorelease pools matter.

Say your answer out loud, then check which of these points you covered:

  • Obj-C autoreleased objects
  • Tight loops
  • autoreleasepool { }

Deep dive

Pure Swift objects aren't autoreleased; ARC frees them directly.

Background threads you create need their own pool; GCD and Swift concurrency provide one.

The modern Swift form is autoreleasepool { }.

Confirm with the Allocations instrument that the spike is autoreleased memory.

Common mistakes

  • Adding pools everywhere 'just in case'.
  • Missing a pool in a long batch-processing loop.

Senior take & follow-ups

Seniors know pools only matter for Objective-C-bridged objects in tight loops.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why does the spike disappear after the loop?

    Show hint

    The run loop drains its pool at the end of the turn.

  2. Do async functions need pools?

    Show hint

    Rarely; but long synchronous loops inside them still can.

Suggest a fix if something here is wrong or out of date.