【问题标题】:Rare crash during dealloc AVCaptureVideoPreviewLayer在 dealloc AVCaptureVideoPreviewLayer 期间发生罕见的崩溃
【发布时间】:2015-04-10 19:21:43
【问题描述】:

在客户端手机上,相机释放期间很少会出现崩溃

Fatal Exception: NSRangeException
Cannot remove an observer <AVCaptureSession 0x174212170> for the key path "changeSeed" from <AVCaptureConnection 0x17420fa60> because it is not registered as an observer.

Thread : Fatal Exception: NSRangeException
0  CoreFoundation                 0x000000018449259c __exceptionPreprocess + 132
1  libobjc.A.dylib                0x0000000194be40e4 objc_exception_throw + 60
2  CoreFoundation                 0x00000001844924dc -[NSException initWithCoder:]
3  Foundation                     0x00000001852a7e9c -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 528
4  Foundation                     0x00000001852a7954 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 104
5  AVFoundation                   0x0000000182d21054 -[AVCaptureSession _removeConnection:] + 192
6  AVFoundation                   0x0000000182d206dc -[AVCaptureSession _removeVideoPreviewLayer:] + 120
7  AVFoundation                   0x0000000182d300f8 -[AVCaptureVideoPreviewLayer dealloc] + 92

对于停止捕获会话,使用以下代码: 所有会话操作都在后台队列中进行,因为 stopRunning 可能需要一些时间

deinit {
  if let session = self.captureSession {
     dispatch_async(self.cameraQueue, { () -> Void in
        session.beginConfiguration()
        let allInputs = session.inputs as! [AVCaptureInput]
        for input in allInputs {
           session.removeInput(input)
        }
        let allOutputs = session.outputs as! [AVCaptureOutput]
        for output in allOutputs {
           session.removeOutput(output)
        }
        session.commitConfiguration()
        session.stopRunning()
     })
  }
}

以前有人见过这种崩溃吗?

【问题讨论】:

标签: ios crash key-value-observing avcapturesession dealloc


【解决方案1】:

我也遇到了这个异常,当我完成预览层时(即在丢弃对预览层的引用之前),为我解决的问题是从 AVCaptureVideoPreviewLayer 取消捕获会话。换句话说,在某些控制器中,我有类似的东西:

previewLayer = AVCaptureVideoPreviewLayer(session: someSession)

previewLayer 是这个控制器的一个属性,然后当我用完previewLayer 后,在控制器的deinit 中我做:

previewLayer.session = nil

不应该这样做,因为当预览层取消初始化时,它也会取消会话。但是我在崩溃案例的堆栈跟踪中看到的是,预览层的 dealloc 没有像通常那样从拥有控制器的 dealloc 调用,而是从NSKVODeallocate 释放。这意味着某些东西(与 KVO 相关?)必须在拥有的控制器释放后一直保留在预览层上,并且稍后才释放它。 (我不知道它是什么或导致它的原因。)也许有一个错误,必须在捕获会话完成之前从预览层取消捕获会话,否则它会崩溃(它不应该,但它做)。这就是为什么我在完成会话后自己明确取消设置的原因。

【讨论】:

    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 2020-08-29
    • 2020-02-24
    • 1970-01-01
    相关资源
    最近更新 更多