WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Memory management with Core Graphics & SwiftUI

Forums > SwiftUI

I'm constructing a bitmap image in memory and displaying it as a SwiftUI Image. Now, the Swift objects should all get cleaned up automatically by Swift's memory management, but there are a couple of calls where Apple's documentation says that the caller is responsible for releasing some memory:

  // in application startup code, there's this:
  let colorSpace = CGColorSpaceCreateDeviceRGB()

Can I handle releasing this CGColorSpace by only creating one and letting it get collected when the application exits?

Later on, in a View struct, I build the Image whenever the array of pixel information gets updated:

    var image: Image {
        let context = CIContext()
        let ciimage = CIImage(bitmapData: makePixelData(),
                              bytesPerRow: 4 * width,
                              size: CGSize(width: width, height: height),
                              format: .ARGB8,
                              colorSpace: colorSpace)
        // This CGImage comes with documentation that says I'm responsible for releasing it!
        if let cgimage = context.createCGImage(ciimage, from: ciimage.extent) {
          // At what point is it even safe to dispose of cgimage?
            return Image(decorative: cgimage, scale: 1.0)
        } else {
            // if we're here, it means we couldn't draw the picture, so we should
            // display some kind of place holder? Or error?
            return Image(systemName: "exclamationmark.triangle.fill")


Hm. So, according to this StackOverflow question, I don't need to worry about releasing the CGImage.

However, when I attach Instruments to my app and use the leak detection tool, it does find some memory leaks, which look like they're happening whenever I update the view state, causing the image to get recreated. The size of the leak(?) is very small, though - much smaller than the array of UInt32 I'm using, so I'm not quite sure what's up. Top line, though, seems to be that the documentation comment applies only to Objective C and not to Swift.


Further investigation with Instruments and the leak detection tool reveals that the call to create a CIImage leaks an IOSurface.

Then, the call to context.createCGImage(_, from:) leaks a block of 272 bytes that malloc reserves inside CGImageCreateFromIOSurface.

The first call is inside CoreImage, while the second is in ImageIO. I hope that these leaks are just because I'm using Xcode 13 beta, but now I wonder if I should file a bug somewhere. Memory leaks are bad enough, but when they're in image rendering code, that's likely to run the system out of memory really, really fast.


Hacking with Swift is sponsored by Fernando Olivares

SPONSORED Fernando's book will guide you in fixing bugs in three real, open-source, downloadable apps from the App Store. Learn applied programming fundamentals by refactoring real code from published apps. Hacking with Swift readers get a $10 discount!

Read the book

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.