Auto-release Pools and Background Threads
In Objective-C on macOS and iOS, an autorelease pool holds objects
that were sent an autorelease message and releases them later, when the pool
is drained. This page explains when you need to manage pools yourself — which
matters whenever you call a library, such as Chilkat, that returns autoreleased
objects.
Jump to: Command-line tools Loops Secondary threads ARC GCD & queues
Most application code does not need to create an autorelease pool manually. AppKit and UIKit automatically create and drain a pool around each pass through the main event loop — for example, when a macOS app handles a mouse event, or an iOS app handles a touch event, the framework provides the pool for that unit of work. There are, however, several situations where you should create your own.
NSString, NSData,
Cko objects, etc.). On the main thread the framework drains the pool for you,
but if you call Chilkat from a secondary thread you created, or in a tight loop,
wrap the work in an @autoreleasepool block so those objects are released
promptly — otherwise memory can grow in a way that looks like a leak.
Command-line tools
A Foundation-based command-line program has no AppKit or UIKit event loop to create a
pool for you. Wrap the main body of the program in an @autoreleasepool block:
int main(int argc, const char * argv[]) { @autoreleasepool { // Program code here. } return 0; }
Loops that create many temporary objects
If a loop creates many temporary Objective-C objects, those autoreleased objects can
accumulate until the outer pool is drained, growing the program's peak memory usage
unnecessarily. Place an @autoreleasepool block inside the loop:
for (int i = 0; i < count; i++) { @autoreleasepool { // Create and use temporary Objective-C objects here. // They are released at the end of this iteration. } }
This is especially useful when processing many files, large collections, images, strings, XML documents, JSON objects, or other short-lived Foundation/Cocoa objects.
Secondary threads
If you create a secondary thread yourself — for example with NSThread
or a lower-level thread API — create an autorelease pool near the beginning of the
thread's entry point. Otherwise, autoreleased objects created on that thread may not be
released promptly, which can look like a memory leak:
- (void)threadMain { @autoreleasepool { // Code executed by the secondary thread. } }
If the thread runs a long-lived loop, it is usually better to place the pool inside the loop so temporary objects are released after each iteration:
- (void)workerThreadMain { while (!shouldStop) { @autoreleasepool { // Perform one unit of work. } } }
ARC does not eliminate autorelease pools
Automatic Reference Counting (ARC) manages most retain and release calls for you, but autorelease pools still exist. Objective-C and Foundation APIs may still return autoreleased objects, and temporary objects can still accumulate until the current pool is drained.
Under ARC you normally do not call retain, release, or
autorelease yourself — you simply use @autoreleasepool
blocks when you need more control over when temporary objects are released.
Grand Central Dispatch and operation queues
With higher-level concurrency APIs such as Grand Central Dispatch (GCD) or operation
queues, the system generally manages the thread machinery for you. Even so, an explicit
@autoreleasepool block can still help inside a dispatched block or operation
that creates many temporary objects:
dispatch_async(queue, ^{ @autoreleasepool { // Work that creates many temporary Foundation/Cocoa objects. } });
This is not always required, but it is good defensive practice for memory-intensive background work.