Search code examples
iosswiftcastingcgimageunsafe-pointers

Casting UnsafeRawPointer to CGImage from C function that returns a CGImageRef Crashes Swift 4


We have a cross platform image processing library and there is a call that returns a CGImageRef as an UnsafeRawPointer which I need to turn into a CGImage. I know the call works as when using it in objective c I can just cast using (CGImageRef) returnedData on the returned data and I get the image. However when trying to use it in our iOS app using Swift 4 I can't seem to cast it without getting an EXC_BREAKPOINT error or a BAD_ACCESS error. I've tried casting using as! CGImage as well as trying pointer.load(as: CGImage.self) and both give me the same result. Am I doing something wrong? is there a better way to pass back an image from C code to swift? I should mention that the same C function takes a CGImageRef as a parameter and passing a CGImage in instead causes no issues whatsoever.


Solution

  • I think it’s a memory management issue. E.g. the CGImageRef that you get is released before you use it. Use “Product" > “Scheme" > "Edit Scheme" menu, select “Run" section, “Diagnostics” tab and enable “Zombie Objects” option. Then run the app. If some object is used after deallocation, you will get a message in the console.

    If that’s the case, something like this should fix the issue:

    // pointer is your UnsafeRawPointer for CGImageRef
    let cgImage = Unmanaged<CGImage>.fromOpaque(pointer).takeRetainedValue()
    

    Better yet, if you can edit or override header files for the library in question, you can annotate C functions to let Swift know how to handle the pointers properly.