What is an autorelease pool, and when does a Swift loop need one?
Predict first
What does this print?
let n = autoreleasepool { 42 }
print(n)
- 42
- ()
- Compile error
Predict first
A batch job converts 100,000 images with Objective-C-backed APIs in one for loop. Where do you put the pool?
// A: around the whole loop
// B: inside the loop body
// C: nowhere, Swift releases immediately
- A
- B
- C
Mental model. An autorelease pool is a tray of plates waiting for the dishwasher. A loop that makes a million plates without running the washer fills the kitchen.
Autorelease means “release this later, not now”. Many Objective-C methods return autoreleased objects so the caller does not have to release them. Each such object is added to the current autorelease pool and released when that pool drains. The main run loop drains a pool every iteration, and each GCD block gets one as well, so you usually never think about it.
Pure Swift objects are released immediately and never touch a pool. But on Apple platforms a Swift loop that calls Objective-C-backed APIs (NSString, NSData, UIImage, many Foundation calls) can park a lot of temporaries in the pool. Until the pool drains, at the end of the whole loop or event, memory keeps climbing. Wrap the loop body in autoreleasepool { … } so each iteration cleans up after itself, and confirm the effect in Instruments. The closure’s return value is passed through.
autoreleasepool returns whatever its body returns, so you can compute a value inside and keep only that.
Inside the body, so each iteration drains its temporaries before the next begins. Around the whole loop it would drain only once, at the end.
Common traps
- “Swift never needs
autoreleasepool.” Any loop that calls Objective-C APIs can still pile up autoreleased objects. - Adding a pool around trivial work. It has a small cost, so use it where a profile shows growth.
They might follow up with
- Where does the pool drain on a worker thread? After each GCD block. A raw thread you create yourself needs its own pool.
- How do you spot the problem? A sawtooth-free, steadily climbing memory graph in Instruments during a batch job.
Related questions
- 3.1.4 What did manual reference counting look like, and which rules did ARC automate?
- 3.6.4 What hidden retains and autoreleases does calling Objective-C add?
← What did manual reference counting look like, and which rules did ARC…