AVFoundation API를 사용하여 카메라 미리보기를 만들었으며 작업을 마친 후에 정리하는 데 문제가 있습니다.AVCaptureSession 및 AVCaptureVideoPreviewLayer를 올바르게 정리하는 방법
이 문제의 가장 좋은 대답은 SO thread입니다. 감사합니다. Codo.
그러나 그는 AVCaptureVideoPreviewLayer의 할당 해제 문제를 해결하지 못하므로 문제가 발생합니다.
내 View Controller 클래스에는 startCameraCapture 메서드에 몇 가지 초기화 코드가 있습니다. Codo의 대답을 듣고, 나는 큐가 정말로 닫힐 때 콜 될 콜백을 등록하기 위해 dispatch_set_finalizer_f(_captureQueue, capture_cleanup);
을 사용하고있다. 대기열에서 내 개체를 호출하기 전에 내 개체가 사라지지 않았는지 확인하기 위해 자기도 보유하고 있습니다. 그런 다음 capture_cleanup 콜백을 사용하여 자체를 릴리스합니다. 여기
-(void) startCameraCapture {
_camSession = [[AVCaptureSession alloc] init];
if (_previewLayer == nil) {
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_camSession];
}
_previewLayer.frame = self.compView.bgView.frame;
[self.compView.bgView.layer addSublayer:_previewLayer];
// Get the default camera device
AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// Create a AVCaptureInput with the camera device
NSError *error=nil;
AVCaptureInput* cameraInput = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error];
if (cameraInput == nil) {
NSLog(@"Error to create camera capture:%@",error);
}
AVCaptureVideoDataOutput* videoOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
// create a queue to run the capture on
_captureQueue=dispatch_queue_create("captureQueue", NULL);
dispatch_set_context(_captureQueue, self);
dispatch_set_finalizer_f(_captureQueue, capture_cleanup);
// setup our delegate
[videoOutput setSampleBufferDelegate:self queue:_captureQueue];
dispatch_release(_captureQueue);
// retain self as a workouround a queue finalization bug in apples's sdk
// per Stackoverflow answer https://stackoverflow.com/questions/3741121/how-to-properly-release-an-avcapturesession
[self retain];
// configure the pixel format
videoOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,
nil];
// and the size of the frames we want
[_camSession setSessionPreset:AVCaptureSessionPresetMedium];
// Add the input and output
[_camSession addInput:cameraInput];
[_camSession addOutput:videoOutput];
[cameraInput release];
// Start the session
[_camSession startRunning];
}
capture_cleanup 콜백 :
static void capture_cleanup(void* p)
{
LiveCompViewController* ar = (LiveCompViewController*)p;
[ar release]; // releases capture session if dealloc is called
}
그런 다음 내 정리 코드는 다음과 같습니다
-(void) stopCameraCapture {
[_camSession stopRunning];
[_camSession release];
_camSession=nil;
// Remove the layer in order to release the camSession
[_previewLayer removeFromSuperlayer];
_previewLayer = nil;
}
제가하는 데 문제는입니다 stopCameraCapture의 superlayer에서 _previewLayer을 제거 다음 콘솔 오류가 발생합니다.
"...modifying layer that is being finalized..."
그러나 레이어를 제거해야 해제되어 _camSession이 해제되어 dispatch_queue가 해제되고 마침내 자신을 릴리스하는 내 capture_cleanup 콜백이 호출됩니다.
콘솔 오류가 발생하는 이유와 해결 방법을 이해할 수 없습니다. self.dealloc이 호출되지 않은 경우 [_previewLayer removeFromSuperlayer]
을 호출 할 때 레이어가 마무리되는 이유는 무엇입니까?
참고 : self는 viewController이며 아직 팝업하지 않았으므로 NavigationContoller에 의해 유지됩니다.