In Swift, the life of CF objects is managed automatically, so you have to consider whether you own a reference to the pixel buffer that lasts long enough to make the passed pointer valid during the callback. (In Obj-C, it was easier, because you could just CFRetain the pixel buffer when you pass it in, and CFRelease it when you're done with it.)
I just ran into a similar issue with a context (void*) pointer passed into a didEnd…-style method, where I used this CFRetain/CFRelease approach in Obj-C and needed a new answer in Swift. What I came up with is this:
private struct PresentErrorContext {
let completionHandler: ((Bool) -> Void)?
}
@objc private func didPresentError (didRecover: Bool, contextInfo rawContextInfo: UnsafeMutableRawPointer?) {
// Invoke the completion handler
if let contextInfo = rawContextInfo?.assumingMemoryBound (to: PresentErrorContext.self) {
if let completionHandler = contextInfo.pointee.completionHandler {
completionHandler (didRecover) }
contextInfo.deinitialize ()
contextInfo.deallocate (capacity: 1)
}
}
func presentErrorAsSheet (_ error: Error, completionHandler: (Bool) -> Void) {
// Allocate some memory for the contextAllocate some memory for the context
let contextInfo = UnsafeMutablePointer<PresentErrorContext>.allocate (capacity: 1)
contextInfo!.initialize (to: PresentErrorContext (completionHandler: completionHandler))
// Display the error sheet
presentError (error, modalFor: window!, delegate: self,
didPresent: #selector (didPresentError(didRecover:contextInfo:)),
contextInfo: contextInfo)
}
That is, I allocated a little bit of memory from the heap to hold the PresentErrorContext structure, and wrapped the actual reference inside that structure. The point is that this memory is not reference counted, hence won't disappear until explicitly deallocated — Swift's own special malloc.
In my case, it was a completion handler reference being passed. In your case, you should be able to do something similar with the pixel buffer reference.
Note: I tried this to make sure it works, but I didn't verify that it's not leaking memory, so use at your own risk. Also, there might be cleverer ways to do this.