Ios 如何正确清理AVCaptureSession和AVCaptureVideoPreviewLayer
我正在使用avfoundationapi创建一个相机预览视图,完成后我在清理方面遇到了问题 我发现这个问题最好的答案就是这个,谢谢Codo 但是,他没有解决AVCaptureVideoPreviewLayer的解除分配问题,这就是我遇到的问题 在我的视图控制器类中,我在startCameraCapture方法中有一些初始化代码。听Codo的回答,我正在使用Ios 如何正确清理AVCaptureSession和AVCaptureVideoPreviewLayer,ios,ios4,Ios,Ios4,我正在使用avfoundationapi创建一个相机预览视图,完成后我在清理方面遇到了问题 我发现这个问题最好的答案就是这个,谢谢Codo 但是,他没有解决AVCaptureVideoPreviewLayer的解除分配问题,这就是我遇到的问题 在我的视图控制器类中,我在startCameraCapture方法中有一些初始化代码。听Codo的回答,我正在使用dispatch\u set\u finalizer\u f(\u captureQueue,capture\u cleanup)注册在队列真
dispatch\u set\u finalizer\u f(\u captureQueue,capture\u cleanup)
注册在队列真正关闭时调用的回调。
我还保留了self,以确保在队列调用完我的对象之前,我的对象不会消失。然后我使用capture\u cleanup回调来释放self
-(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会导致以下控制台错误:
“…修改正在最终确定的图层…”
但是我需要删除该层,以便它被释放和释放,从而释放_camSession,然后释放dispatch_队列,最后调用我的capture_cleanup回调,最终释放self
我不明白为什么会出现控制台错误以及如何修复它。如果没有调用self.dealloc,为什么在我调用[[u previewLayer removeFromSuperlayer]
时该层正在最终确定
注意:self是一个viewController,我还没有弹出它,因此它由NavigationController保留。在释放之前尝试停止会话:
[captureSession stopRunning];