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)?
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 like the following:
But if you do it without the autorelease pool, you'll see that peak memory usage is higher:
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.