(void)captureOutput:(AVCaptureOutput )captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection )connection
调用这个代理方法 偶尔会崩溃 bugly显示如下
8 AVFoundation -[AVCaptureVideoDataOutput _handleRemoteQueueOperation:] + 344
9 AVFoundation ___47-[AVCaptureVideoDataOutput _updateRemoteQueue:]_block_invoke + 100
10 CoreMedia ___FigRemoteOperationReceiverCreateMessageReceiver_block_invoke + 272
11 CoreMedia ___FigRemoteQueueReceiverSetHandler_block_invoke.2 + 224
12 libdispatch.dylib __dispatch_client_callout + 16### 问题描述
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
pragma mark 相机相关
-
(AVCaptureSession *)captureSession {
if (!_captureSession) {//创建会话层 _captureSession = [[AVCaptureSession alloc] init]; [_captureSession setSessionPreset:AVCaptureSessionPreset1920x1080];
}
return _captureSession;
}
-
(AVCaptureDeviceInput *)captureInput {
if (!_captureInput) {_captureInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
}
return _captureInput;
}
-
(AVCaptureStillImageOutput *)captureOutput {
if (!_captureOutput) {//创建、配置输出 _captureOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]; [_captureOutput setOutputSettings:outputSettings];
}
return _captureOutput;
}
-
(AVCaptureVideoDataOutput *)captureDataOutput {
if (!_captureDataOutput) {_captureDataOutput = [[AVCaptureVideoDataOutput alloc] init]; _captureDataOutput.alwaysDiscardsLateVideoFrames = YES; dispatch_queue_t queue = dispatch_queue_create("cameraQueue", NULL); [_captureDataOutput setSampleBufferDelegate:self queue:queue]; NSString* formatKey = (NSString*)kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:formatKey]; [_captureDataOutput setVideoSettings:videoSettings];
}
return _captureDataOutput;
}
-
(AVCaptureVideoPreviewLayer *)capturePreviewLayer {
if (!_capturePreviewLayer) {_capturePreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession]; _capturePreviewLayer.frame = CGRectMake(0,0, ScreenW, ScreenH); _capturePreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
}
return _capturePreviewLayer;
}
-
(AVCaptureDevice *)captureDevice {
if (!_captureDevice) {NSArray *deviceArr = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *device in deviceArr) { if (device.position == AVCaptureDevicePositionBack){ _captureDevice = device; _captureInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; } }
}
return _captureDevice;
}
//输入设备
if ([self.captureSession canAddInput:self.captureInput]) {
[self.captureSession addInput:self.captureInput];
}
//输出设备
if ([self.captureSession canAddOutput:self.captureDataOutput]) {
[self.captureSession addOutput:self.captureDataOutput];
}
//输出设备
if ([self.captureSession canAddOutput:self.captureOutput]) {
[self.captureSession addOutput:self.captureOutput];
}
//添加预览层
[self.view.layer addSublayer:self.capturePreviewLayer];
[self.view.layer addSublayer:self.detectLayer];
self.view.layer.masksToBounds = YES;
[self.view addSubview:self.squareView];
这个 queue 放在作为函数的局部变量,不合适。
系统的代理回调在一个创建的局部的队列变量中执行,
然后如果碰巧这个 queue 没被系统回收,代理就调用有效。
如果这个 queue 被系统回收了,代理调用有崩
这个肯定不能放在函数内创建,
dispatch_queue_t queue
看到就怪怪的
你可以用系统提供的队列。
如果要用你自定制的,
苹果是这么做的
使用 AVFoundation, 苹果的实例代码, 你应该看一下。
AFN 用的是单例。