当我不再需要该会话和所有相关对象时,我停止捕获会话并将其释放。这在大多数情况下都有效。但是,有时应用程序会崩溃,并在由调度队列创建的第二个线程中引发 EXEC_BAD_ACCESS
信号(此线程处理视频样本)。崩溃主要是由于我的类实例造成的,它充当样本缓冲区委托,并在我停止捕获会话后被释放。
苹果文档提到了这个问题:停止捕获会话是一个异步操作。也就是说,它不会立即发生。特别是第二个线程继续处理视频样本并访问不同的实例,如捕获会话或输入和输出设备。
那么,我该如何正确释放 AVCaptureSession
和所有相关实例?是否有一种可靠的通知告诉我 AVCaptureSession
已经完成?
以下是我的代码:
声明:
AVCaptureSession* session;
AVCaptureVideoPreviewLayer* previewLayer;
UIView* view;
实例的设置:
AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
session = [[AVCaptureSession alloc] init];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice: camera error: &error];
[session addInput: input];
AVCaptureVideoDataOutput* output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput: output];
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession: session] retain];
previewLayer.frame = view.bounds;
[view.layer addSublayer: previewLayer];
[session startRunning];
清理:
[previewLayer removeFromSuperlayer];
[previewLayer release];
[session stopRunning];
[session release];