我有一个主视图控制器,它会转向第二个具有avcapturesession的视图控制器。我第一次从主视图控制器切换到捕获会话控制器,大约需要50ms(使用“仪器”检查)。然后我从捕获会话中回到主视图控制器,然后从主控制器返回到avcapturesession控制器。每次从主视图控制器切换到avcapturesession需要更长的时间,并且通过第5次或第6次迭代,segue需要大约10秒。 (与第一次50ms相比。)我已经粘贴了下面的avcapture会话的相关代码。谁能帮忙解决这个问题?感谢
此类(NSObject类型)管理第二个视图控制器的捕获会话
实际上实现了avcapturesession
#import "CaptureSessionManager.h"
@implementation CaptureSessionManager
@synthesize captureSession;
@synthesize previewLayer;
#pragma mark Capture Session Configuration
- (id)init {
if ((self = [super init])) {
[self setCaptureSession:[[AVCaptureSession alloc] init]];
}
return self;
}
- (void)addVideoPreviewLayer {
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
- (void)addVideoInput {
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (videoDevice) {
NSError *error;
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (!error) {
if ([[self captureSession] canAddInput:videoIn])
[[self captureSession] addInput:videoIn];
//else
// NSLog(@"Couldn't add video input");
}
// else
// NSLog(@"Couldn't create video input");
}
//else
// NSLog(@"Couldn't create video capture device");
}
- (void)dealloc {
[[self captureSession] stopRunning];
[previewLayer release], previewLayer = nil;
[captureSession release], captureSession = nil;
[super dealloc];
}
@end
以下是avcapture视图控制器的viewdidLoad方法:
[self setCaptureManager:[[CaptureSessionManager alloc] init]];
[[self captureManager] addVideoInput];
[[self captureManager] addVideoPreviewLayer];
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),
CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
[[captureManager captureSession] startRunning];
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:YES];
[[[self captureManager] previewLayer]removeFromSuperlayer];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[captureManager captureSession] stopRunning];
});
}
答案 0 :(得分:7)
我遇到同样的问题我发现这一行是主要问题
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
在解除分配时,只需从超级层移除预览层,并且没有内存问题。我的解除分配功能如下
-(void)deallocSession
{
[captureVideoPreviewLayer removeFromSuperlayer];
for(AVCaptureInput *input1 in session.inputs) {
[session removeInput:input1];
}
for(AVCaptureOutput *output1 in session.outputs) {
[session removeOutput:output1];
}
[session stopRunning];
session=nil;
outputSettings=nil;
device=nil;
input=nil;
captureVideoPreviewLayer=nil;
stillImageOutput=nil;
self.vImagePreview=nil;
}
我在弹出并推送任何其他视图之前调用了此函数。它解决了我的问题。
答案 1 :(得分:5)
删除会话输入和输出似乎为我解决了这个问题
[captureSession stopRunning];
for(AVCaptureInput *input in captureSession.inputs) {
[captureSession removeInput:input];
}
for(AVCaptureOutput *output in captureSession.outputs) {
[captureSession removeOutput:output];
}
答案 2 :(得分:1)
Swift版TUNER88的回答
func stopRecording() {
captureSession.stopRunning()
for input in captureSession.inputs {
captureSession.removeInput(input)
}
for output in captureSession.outputs {
captureSession.removeOutput(output)
}
}
答案 3 :(得分:0)
您似乎没有删除avcaptureViewController中的previewLayer,后者会在内部保留对捕获会话的引用。确保从该视图层次结构中删除了previewLayer。
答案 4 :(得分:0)
Swift 3
let session = AVCaptureSession()
if let outputMovie = outputMovie, outputMovie.isRecording {
outputMovie.stopRecording()
}
self.session.stopRunning()
if let inputs = self.session.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
self.session.removeInput(input)
}
}
if let outputs = self.session.outputs as? [AVCaptureOutput] {
for output in outputs {
self.session.removeOutput(output)
}
}
答案 5 :(得分:0)
对我有用的是将类型previewLayer
的{{1}}设置为弱变量,然后在AVCaptureVideoPreviewLayer()
函数中,我有:
stopCaptureSession()
事实证明,我所有的问题都连接到了PreviewLayer
答案 6 :(得分:-1)
这是TUNER88答案的快速版本
session.stopRunning()
for(var i = 0 ; i < session.inputs.count ; i++){
session.removeInput(session.inputs[i] as! AVCaptureInput)
}
for(var i = 0 ; i < session.outputs.count ; i++){
session.removeOutput(session.outputs[i] as! AVCaptureOutput)
}