orthehelper
orthehelper

Reputation: 4079

AVCaptureSession stopRunning() Mysterious Crash

Recently I got notified about a crash from firebase and this is the message:

[AVCaptureSession stopRunning] stopRunning may not be called between calls to beginConfiguration and commitConfiguration 

I went through my code and the weirdest part is I never call and there is no mention nowhere of beginConfiguration() and commitConfiguration().

In my CameraManager class this is the function that triggers the crash, it called on deinit:

  func stop() {
    guard isStarted else { return Log.w("CameraManager wasn't started") }
    queue.async {
        self.isStarted = false
        self.isCapturingFrame = false
        self.isCapturingCode = false
        self.session?.stopRunning()
        self.session = nil
        self.device = nil
    }
    notificationCenter.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    layer.removeFromSuperlayer()
    layer.session = nil
}

The queue is just a serial disptach queue. No matter what I tried, I couldn't reproduce this crash. Tried pulling the menu, push notification, phone call, simulate memory warning etc... Just to clarify, there is not a single place in my code calling beginConfiguration and commitConfiguration.

Upvotes: 6

Views: 2443

Answers (1)

Frank Rupprecht
Frank Rupprecht

Reputation: 10383

I could imagine that layer.session = nil will cause a re-configuration of the capture session (since the connection to the preview layer is removed). And since you are calling stopRunning() async, I guess you can run into race conditions where stopRunning() gets called right in the middle of the configuration change.

I would suggest you either try to make the cleanup calls synchronous (queue.sync { ... }) or move the layer cleanup into the async block as well.

Upvotes: 7

Related Questions