在客户端手机上,很少可以在相机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()
})
}
}
有没有人见过这次崩溃?
答案 0 :(得分:4)
我也遇到了这个异常,而且当我完成预览图层(即丢弃对预览图层的引用之前)时,修复它的是从AVCaptureVideoPreviewLayer
取消捕获会话。换句话说,在某些控制器中我有类似的东西:
previewLayer = AVCaptureVideoPreviewLayer(session: someSession)
其中previewLayer
是此控制器的属性,然后当我完成previewLayer
时,在控制器的deinit
中执行:
previewLayer.session = nil
没有必要这样做,因为当预览图层取消初始化时,它也会使会话失效。但是我所看到的崩溃案例中的堆栈跟踪是因为预览层的dealloc没有像通常那样从拥有控制器的dealloc中调用,而是从NSKVODeallocate
解除分配。这意味着(拥有KVO?)必须在拥有控制器解除分配后保留在预览层上,并且稍后才释放它。 (我不知道它是什么或是什么导致它。)也许有一个错误,必须在捕获会话完成之前从预览层取消捕获会话或它崩溃(它不应该,但它一样)。这就是为什么当我完成它时我自己明确地取消了会话。