使用 AVCaptureSession 和 AVCaptureVideoPreviewLayer(以编程方式)正确关闭视图控制器

问题描述 投票:0回答:3

点击相机按钮时,我将展示一个新的视图控制器(cameraVC)。 cameraVC 有一个 AVCaptureSession 可以拍摄照片和视频,也可以使用麦克风并将其全部显示在 AVAcptureVideoPreviewLayer 上。一切都很好。但是,当我使用 dismiss() 函数关闭 cameraVC 时,我不确定如何正确清理其余部分,以便 cameraVC 及其组件完全取消分配/释放。当我再次点击相机按钮时,相同的捕获会话仍在运行。事实上,如果我在按下关闭按钮之前开始录制视频,即使 cameraVC 不再显示,相机也会继续录制。我想在点击关闭按钮时完全关闭 cameraVC,包括停止和取消分配该捕获会话和预览层。

我试过,在调用 dismiss()、session.stopRunning() 和 self.previewLayer.removeFromSuperLayer() 之前。它在他们这样做的意义上起作用,但实际的 cameraVC 没有取消分配,所以当我再次点击相机按钮时,从 viewDidLoad() 中调用的实例化会话和预览层的函数不会再次调用。我意识到我可以在 viewWillAppear() 中调用这些相同的函数,但是一旦第一次点击相机按钮就不要让这些东西在后台持续运行不是更好的做法吗?还是建议在调用后在后台进行暂停的相机会话?

更多:当我在 cameraVC 上调用 dismiss() 时,会调用 viewWillDisappear(),但不会调用 deinit()。有人可以帮助解释如何进行这项工作,和/或这背后的机制是什么?非常感谢。

ios swift avcapturesession dismiss
3个回答
1
投票

我做三件事,

deinit
总是被召唤。

在我的演示者中,我有一个班级相机VC,所以我在

viewWillAppear
中将它设置为零。

在 CameraVC 中,我使用 CMMotionManager 并在其上调用 stopAccelerometerUpdates。

要停止 AVCaptureSession,我调用以下方法:

func stopCaptureSession() {
  captureSession.stopRunning()

  if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
    for input in inputs {
      captureSession.removeInput(input)
    }
  }
}

0
投票

我使用

AVCaptureSession
AVCaptureVideoPreviewLayer
作为弱变量。

weak var session: AVCaptureSession!
weak var layer: AVCaptureVideoPreviewLayer!

0
投票

释放AVCaptureSession

两个要点

  • 使用
    .stopRunning()
    功能
  • 不要创建保留周期[关于]。例如,如果您使用
    VNRecognizeTextRequest
let textRequest = VNRecognizeTextRequest(completionHandler: { [weak self] (request, error) in
    guard let self = self else { return }
    self.handleDetectedText(request: request, error: error)
})
© www.soinside.com 2019 - 2024. All rights reserved.