NEW: Learn to build the incredible iOS 15 Weather app today! >>

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 Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS, you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Learn More

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

Reply to this topic…

You need to create an account or log in to reply.

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.