Как правильно выпустить AVCaptureSession

Я использую классы AV Foundation для захвата живого видеопотока с камеры и обработки образцов видео. Это хорошо работает. Однако у меня действительно есть проблемы с правильным выпуском экземпляров основы AV (сеанс захвата, слой предварительного просмотра, ввод и вывод), как только я закончу.

Когда мне больше не нужен сеанс и все связанные объекты, я прекращаю сеанс захвата и освобождаю его. Это работает большую часть времени. Однако иногда происходит сбой приложения с сигналом EXEC_BAD_ACCESS, возникающим во втором потоке, который был создан в очереди отправки (и где обрабатываются образцы видео). Сбой происходит в основном из-за моего собственного экземпляра класса, который служит примером буфера делегата и освобождается после того, как я остановил сеанс захвата.

В документации Apple упоминается проблема: остановка сеанса захвата является асинхронной операцией. То есть: это происходит не сразу. В частности, второй поток продолжает обрабатывать образцы видео и получать доступ к различным экземплярам, ​​таким как сеанс захвата или устройства ввода и вывода.

Так как же правильно освободить 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];