Object autoreleased inside a loop that never drains

ID

objectivec.performance.autorelease_in_loop

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Performance

Language

Objective-C

Description

Reports a for or while body that sends autorelease without wrapping the work in an @autoreleasepool. The innermost loop around the call is the one reported, and a loop whose body - at any depth - opens an @autoreleasepool is left alone.

Rationale

An autoreleased object is not deallocated when the iteration ends; it is registered with the pool that is current at the time, and on the main thread that pool is drained by the run loop only once the whole method has returned. Every iteration therefore adds to a pool that nothing empties, so peak memory grows with the iteration count rather than staying flat. Over a large collection, or a file-per-iteration import, that is the difference between a constant footprint and one that climbs until the system terminates the app for memory pressure - and because each individual object is small and correctly released in the end, the growth does not look like a leak in Instruments.

The following code illustrates the pattern detected by this rule:

@implementation ImageBatch
- (void)renderAll:(NSArray *)paths {
    // FLAGGED: Object autoreleased inside a loop that never drains
    for (NSString *path in paths) {
        NSData *data = [[[NSData alloc] initWithContentsOfFile:path] autorelease];
        [self render:data];
    }
}

- (void)render:(id)item { }
- (void)log:(NSString *)text { }
- (void)flush { }
- (BOOL)hasPending { return NO; }
@end

Remediation

Wrap the body of the loop in @autoreleasepool { …​ } so each iteration drains before the next begins. Where the loop is hot and the objects are small, drain every N iterations instead of every one. Under ARC the explicit autorelease disappears but the pool is still required, because framework convenience constructors return autoreleased objects too.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved