【问题标题】:Leak when converting CIImage to CGImage inside main queue在主队列中将 CIImage 转换为 CGImage 时泄漏
【发布时间】:2015-11-17 13:18:06
【问题描述】:

我正在 Xcode 7.1 iOS 9.1 (swift) 中创建一个简单的应用程序。该应用程序从相机获取一个 CMSampleBuffer,将其转换为 CGImage 并将其分配给 UIImageView。当应用程序在相机队列中将 CIImage 转换为 CGImage 时,应用程序运行良好。但是当应用程序在主队列中转换它时,应用程序就会泄漏。

这是泄露的版本:

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)
    })
}

如果我在 dispatch_sync 中注释“let cgimg”并在上面取消注释,应用程序不会泄漏。但对于我的应用,我需要在主队列中进行转换。

问题似乎与 dispatch_sync 块内的引用计数有关。

有人能解释一下泄漏吗?

问候, 瓦莱里。

【问题讨论】:

  • 您可以像注释代码一样在外部声明 cgimg 并且可以在 dispatch_sync 中使用弱引用,我在 Obj-C 中这样做过,但不知道 swift
  • 如果我取消注释,使用“弱”并不重要。 “让 cgimg ...” 外部同步效果很好,没有任何泄漏。但我需要在同步中调用 createCGImage。还是我错过了什么?
  • 为什么你“必须”在同步中调用 createCGImage ???
  • 我向 Apple 提交了一个错误。他们在 6 个月内修好了。

标签: ios swift memory-leaks


【解决方案1】:

如果你想在块内访问cgimg,那么你应该把它变弱。

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

【讨论】:

  • 我需要在块内调用 createCGImage。我删除了所有额外的代码来解释我有什么问题。在应用程序中,我将 cimg 传递给我的 ViewController。它应用了一些 CI 过滤器,然后使用 createCGImage 创建 CGImage。我得到了泄漏。
  • 你的意思是:? dispatch_sync(dispatch_get_main_queue(), { weak var cgimg = ViewController.cicontext.createCGImage(ciimg, fromRect:ciimg.extent) self.imageView.image = UIImage(CGImage: cgimg!) }) 这段代码崩溃了。
【解决方案2】:

sync 操作中不能引用强对象。试试这个;

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)
        })
    }

【讨论】:

  • 如果我在你的代码中删除“弱”,就不会有任何泄漏。问题是如果我在块内调用 createCGImage 应用程序会泄漏。我必须在块内调用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2016-11-21
  • 2014-06-07
相关资源
最近更新 更多