'Why does a new Objective-C project's boilerplate contain an autorelease pool block, but a new Swift project doesn't?
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
}
return NSApplicationMain(argc, argv);
}
Why is this important enough that boilerplate includes it in a new Objective-C project but not a new Swift one?
Solution 1:[1]
Xcode's project templates aren't documented in any meaningful way, so it's not possible to give a definitive answer — but, there are a few likely contributing factors, mostly historical.
Before the introduction of ARC helping automate reference counting, Objective-C required entirely manual memory management. One strategy for more loosely managing allocations in an "automated" way was using
-autoreleaseto dispose of an object eventually by adding it to a global (possibly-nested) pool of objects that could be disposed when the pool itself was disposed of. This was itself manual through the creation of autorelease pools with-[[NSAutoreleasePool alloc] init]and-[NSAutoreleasePool drain]/-[NSAutoreleasePool release]. When calling-autoreleaseon an object, the Obj-C runtime would find the "closest" active autoreleasepool and register the object with that pool, to be disposed of once the pool went away.In order to be able to
-autoreleasean object, there had to be anautoreleasepool actually active to capture the object — it doesn't appear to be this way anymore, but-autoreleaseing an object outside of any pools used to log an error (since nothing could really safely be done except leak the object forever). In order to avoid this, the default Xcode template added an implicit autoreleasepool around the entirety of the code inmain, to ensure that there was at least some pool active in order to capture objects without error. (In fact, before the introduction of@autoreleasepool { ... }blocks, which implicitly creates an autoreleasepool before the execution of the contained code, and releases it after, the Xcode template used to manually create an autoreleasepool and release it before returning frommain)The advent of ARC made autoreleasing significantly less necessary, so much so that Swift doesn't even have a native concept of autoreleasepools. (
autoreleasepoolin Swift is actually a function from theObjectiveCmodule which calls out to the Obj-C runtime to wrap the invoked closure in an autoreleasepool.) Although occasionally useful, they're not typically necessary except when interfacing with Objective-C code which still uses manual memory management and vends autoreleased objects, especially in a tight loop. This comes up occasionally when interfacing with (mostly Apple-based) frameworks like Foundation, which might still have components written with manual memory management in mindThere's also the matter of the usefulness of a global autoreleasepool created this way: since the outermost autoreleasepool created this way will only release objects right before program exit, objects released to the default outermost pool are almost effectively leaked for the duration of execution, since there's nothing that will clean them up earlier
So between a lack of need in Swift, a lack of utility, and the non-existence of autoreleasing as a concept outside of Darwin platforms, there's really not much of a need for Xcode to so directly expose the concept in Swift project templates like it used to be necessary for Objective-C. Likely for brevity, not paying the cost of the creation of a pool, and not confusing non-Obj-C code authors, this was left out of the template.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Itai Ferber |
