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)?
Overview. An autorelease pool stores objects that are sent a release message when the pool itself is drained. Important. If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks.
Automatic Reference Counting (ARC) is a memory management option for Objective-C provided by the Clang compiler. When compiling Objective-C code with ARC enabled, the compiler will effectively retain, release, or autorelease where appropriate to ensure the object's lifetime extends through, at least, its last use.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With