76

In Swift, I notice there is no @autoreleasepool{} construct, although Swift does use ARC. What is the proper way to manage an autoreleasepool in Swift, or has it been removed for some reason?

Skotch
  • 3,072
  • 2
  • 23
  • 43
  • maybe it is just not released to us yet (and implemented a custom one with ObjC bridge is easy) – Bryan Chen Jun 10 '14 at 22:47
  • 1
    Also related and interested: "Is it necessary to use autoreleasepool in a Swift program?" http://stackoverflow.com/questions/25860942/is-it-necessary-to-use-autoreleasepool-in-a-swift-program?rq=1 – Valentin Shergin Mar 30 '16 at 00:07

4 Answers4

118

The syntax is as follows:

autoreleasepool {
  /* code */ 
}

Unfortunately Apple's WWDC 2014 videos no-longer seem to be available. Incase it comes back, it was covered in WWDC 2014 session video number 418 "Improving Your App with Instruments".

The swift documentation doesn't contain anything useful currently. But you can find plenty of good information under the Obj-C Runtime Reference for NSAutoreleasePool and the Advanced Memory Management Programming Guide.

Note: Auto Release Pools are no-longer as relevant today as they were in the past. Modern code should use Automatic Reference Counting which does not use release pools at all. However there's still a lot of legacy code, including in Apple's frameworks, that use auto release pools as of 2021. If you're doing any kind of batch process on images as one example, you probably should be using an autoreleasepool block.

Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110
  • 7
    It's important to note that the `{` **must** be on the same line as the `autoreleasepool`, otherwise you have to wrap it in `( )`. That *really* irks me to be honest... – Erik Jun 10 '14 at 22:59
  • 1
    @SiLo really? That sucks. You should file a bug report. – Abhi Beckert Jun 10 '14 at 23:13
  • 19
    @AbhiBeckert @SiLo It's not a bug. `autorelease` is a function that takes a closure as an argument. This is an example of the short-hand closure-as-last-argument syntax. – Cezary Wojcik Jun 10 '14 at 23:16
  • 1
    @CezaryWojcik Right, but why does it matter if I place the `{` on a new line instead of right after? – Erik Jun 10 '14 at 23:21
  • 7
    @SiLo Since there are no semicolons, if the closure is on the next line, then there isn't a syntactic guarantee that that closure is supposed to be an argument for the function above it. You can see the same thing in JavaScript when you try to do something like `return { ... }`. – Cezary Wojcik Jun 10 '14 at 23:32
  • 1
    @CezaryWojcik ah, that makes sense. Here's a gist explaining it in code: https://gist.github.com/abhibeckert/2a9006d3f24a0937a932 — basically since there are no semicolons to terminate lines the compiler doesn't have any way to link the two statements together. It's a shame, but probably not avoidable. – Abhi Beckert Jun 10 '14 at 23:35
  • @AbhiBeckert Interestingly, that video says that this is used when "working with Objective-C". In my experimentation, it really is only needed when dealing with Objective-C objects (inc Cocoa classes), but not pure Swift objects. I'm digging around to see if I can find some documentation of this (other than the parenthetical reference in this video) and I'm not finding anything. Have you found any document about this `autorelease` function (and its use with Objective-C vs Swift objects)? – Rob Sep 17 '14 at 03:55
  • @Rob I haven't looked into it myself. Autorelease pools aren't needed very often, and my experience any time you do need to work with autorelease pools you should be working with Apple's lower level C APIs instead of Objective-C. If you need to manage memory manually, you should drop down to a low level language and actually manage it manually. It's entirely plausible Apple simply hasn't implementing anything like auto release in Swift, since the language isn't intended to be used in ways that need it. I'm not surprised it's obj-c only. I bet it works on swift classes subclassing NSObject BTW. – Abhi Beckert Sep 20 '14 at 22:28
  • @AbhiBeckert I'll respectfully disagree that one should go to C APIs just because you need to drain the pool: I'd always stay at the highest possible level of abstraction and they provide us the ability to create our own pools for a reason. And [this discussion on Apple's forums](https://devforums.apple.com/thread/245787) makes me think that it's not the case that Swift "hasn't implemented anything like autorelease in Swift", but merely that the now default to +1 objects with transferred ownership now "wherever possible" (which is a cleaner, IMHO) but still support autorelease as needed. – Rob Sep 21 '14 at 01:19
  • @Rob I agree this in itself is not a reason to drop down to C. However I suspect there is a very high correlation between times when you need to deal with autorelease pools and times when you should be using C instead. I know I've only ever had to deal with autorelease pools when I need to process hundreds of megabytes of data, and in pretty much all these cases I have, eventually, thrown the code out and re-written it in C — autorelease works fine but when you're working with large amounts of memory, often you need to tell the compiler _exactly_ what to do, not just give it a few hints. – Abhi Beckert Sep 25 '14 at 00:43
  • @Cezary and that is one of the reasons, why it has been an extremely bad idea to design another programming language that uses line breaks instead of semicolons to mark the end of a statement - whitespaces that are syntactically significant are one of the most outstanding marks of terrible language design. – Kaiserludi Jul 21 '15 at 14:24
  • 1
    I couldn't find this video online. It looks like Apple took it down. I also tried the Apple `Developer.app` from the Mac App Store. – Ben Butterworth Jun 04 '21 at 12:40
  • @BenButterworth You're right, only a handful of videos from WWDC 2014 are still available. I've updated my answer to include the best available alternative I could find after a quick look. – Abhi Beckert Jun 10 '21 at 03:52
16

Just FYI, Xcode constructed the full code as follows:

autoreleasepool({ () -> () in
    // code              
})

Guess the parentheses identifies the functions closure.

Saukwood
  • 301
  • 2
  • 3
  • 3
    not sure why anyone de-voted this comment, as he's pointing out that an autorelease pool as far as swift1.2 needs the code to be wrapped in a closure – bolnad Jun 29 '15 at 15:36
7

There is! It's just not really mentioned anywhere.

autoreleasepool {
    Do things....
}
Joshua Weinberg
  • 28,598
  • 2
  • 97
  • 90
1

I used this kind of structure in my code. This function is create thumbnail image from Video URL.

func getThumbnailImage(forUrl url: URL) -> UIImage? {
    return autoreleasepool{ () -> UIImage in
        let asset: AVAsset = AVAsset(url: url)
        let imageGenerator = AVAssetImageGenerator(asset: asset)
        var thumbnailImage: CGImage?
        do {
            thumbnailImage = try imageGenerator.copyCGImage(at: CMTimeMake(value: 1, timescale: 60) , actualTime: nil)
            return UIImage(cgImage: thumbnailImage!)
        } catch let error {
            print(error)
        }
        return UIImage(cgImage: thumbnailImage!)
    }
}
Yogesh Patel
  • 1,893
  • 1
  • 20
  • 55