vvkatwss vvkatwss
vvkatwss vvkatwss

Reputation: 3579

Leak when converting CIImage to CGImage inside main queue

I am creating a simple application in Xcode 7.1 iOS 9.1 (swift). The app takes a CMSampleBuffer from camera, converts it to CGImage and assigns it to UIImageView. When the app converts CIImage to CGImage inside the camera queue, the app works great. But when the app converts it inside the main queue, the app leaks.

Here is the leaked version:

func captureOutput(captureOutput: AVCaptureOutput!,didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,fromConnection connection: AVCaptureConnection!) {

    let buffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
    let ciimg = CIImage(CVPixelBuffer: buffer)
//  let cgimg = ViewController.cicontext.createCGImage(ciimg, fromRect: ciimg.extent)

    dispatch_sync(dispatch_get_main_queue(), {
        let cgimg = ViewController.cicontext.createCGImage(ciimg, fromRect: ciimg.extent)

        self.imageView.image = UIImage(CGImage: cgimg)
    })
}

If I comment "let cgimg" inside dispatch_sync and uncomment it above, the app does not leak. But for my app, I need to convert it inside the main queue.

It seems that the issue relates to reference counting inside dispatch_sync block.

Could anybody explain the leak?

Regards, Valery.

Upvotes: 0

Views: 738

Answers (2)

Apurv
Apurv

Reputation: 17186

If you want to access cgimg inside block then you should make it weak.

weak let cgimg = ViewController.cicontext.createCGImage(ciimg, fromRect: ciimg.extent)

Upvotes: 1

Kemal Can Kaynak
Kemal Can Kaynak

Reputation: 1658

You can not reference strong object in sync operation. Try this;

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,fromConnection connection: AVCaptureConnection!) {

        let buffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
        let ciimg = CIImage(CVPixelBuffer: buffer)
        weak let cgimg = ViewController.cicontext.createCGImage(ciimg, fromRect: ciimg.extent)

        dispatch_sync(dispatch_get_main_queue(), {
            self.imageView.image = UIImage(CGImage: cgimg)
        })
    }

Upvotes: 0

Related Questions