Ethan
Ethan

Reputation: 18864

Is it necessary to use autoreleasepool in a Swift program?

On page 17 of this WWDC14 presentation, it says

Working with Objective-C? Still have to manage autorelease pools
autoreleasepool { /* code */ }

What does that mean? Does it mean that if my code base doesn't have any Objective-C files, autoreleasepool {} is unnecessary?

In an answer of a related question, there is an example where autoreleasepool can be useful:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

If the code above gets translated into Swift with autoreleasepool dropped, will Swift be smart enough to know that the number variable should be released after the first } (like some other languages does)?

Upvotes: 114

Views: 61038

Answers (3)

Rob
Rob

Reputation: 437532

The autoreleasepool pattern is used in Swift when returning autorelease objects (created by either your Objective-C code or using Cocoa classes). The autorelease pattern in Swift functions much like it does in Objective-C. For example, consider this Swift rendition of your method (instantiating NSImage/UIImage objects):

func useManyImages() {
    let filename = pathForResourceInBundle
    
    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

If you run this in Instruments, you'll see an allocations graph with 5 small hills (because outer for-loop), like the following:

with autoreleasepool

But if you do it without the autorelease pool, you'll see that peak memory usage is higher:

without autoreleasepool

The autoreleasepool allows you to explicitly manage when autorelease objects are deallocated in Swift, just like you were able to in Objective-C.

Note: When dealing with Swift native objects, you generally will not receive autorelease objects. This is why the presentation mentioned the caveat about only needing this when "working with Objective-C", though I wish Apple was more clear on this point. But if you're dealing with Objective-C objects (including Cocoa classes), they may be autorelease objects, in which case this Swift rendition of the Objective-C @autoreleasepool pattern is still useful.

Upvotes: 255

yoAlex5
yoAlex5

Reputation: 34225

@autoreleasepool can be used in Objective-C and Swift code to guarantee working with Objective-C code which relies on autorelease

[Under the hood]

Upvotes: 0

newacct
newacct

Reputation: 122439

If you would use it in the equivalent Objective-C code, then you would use it in Swift.

will Swift be smart enough to know that the number variable should be released after the first }

Only if Objective-C does. Both operate along the Cocoa memory management rules.

Of course ARC knows that number goes out of scope at the end of that iteration of the loop, and if it retained it, it will release it there. However, that does not tell you whether the object was autoreleased, because -[NSNumber numberWithInt:] may or may not have returned an autoreleased instance. There is no way you can know, because you don't have access to the source of -[NSNumber numberWithInt:].

Upvotes: 5

Related Questions