ios – 在dealloc AVCaptureVideoPreviewLayer期间罕见崩溃

在客户端手机上,很少可以在相机dealloc期间复制崩溃

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

以前有人见过这次撞车吗?

解决方法

我也有这个例外,当我完成预览图层时(即在丢弃对预览图层的引用之前),为我修复它的是从AVCaptureVideoPreviewLayer取消捕获会话.换句话说,在某些控制器中我有类似的东西:

previewLayer = AVCaptureVideoPreviewLayer(session: someSession)

其中previewLayer是这个控制器的属性,然后当我完成了previewLayer时,在控制器的deinit中我做了:

previewLayer.session = nil

没有必要这样做,因为当预览层取消初始化时,它也会使会话失效.但是我所看到的崩溃案例中的堆栈跟踪是因为预览层的dealloc没有像通常那样从拥有控制器的dealloc中调用,但是它正在从NSKVODeallocate中释放出来.这意味着(拥有KVO?)必须在拥有控制器解除分配后保留在预览层上,并且稍后才释放它. (我不知道它是什么或是什么导致它.)也许有一个错误,必须在捕获会话完成之前从预览层取消捕获会话或它崩溃(它不应该,但它一样).这就是为什么当我完成它时我自己明确地取消了会话.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...