2015-07-31 2 views
2

Je suis en train de capturer des images et enregistrer des vidéos de caméra, mais chaque fois que je rejette mon point de vue avec caméra je reçois cette erreur:NSRangeException - ne peut pas supprimer observateur

Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer App.CameraViewController 0x16ea7f70 for the key path "movieFileOutput.recording" from App.CameraViewController 0x16ea7f70 because it is not registered as an observer.' *** First throw call stack: (0x2a9e6fef 0x3908ac8b 0x2a9e6f35 0x2b6850f5 0x2b684b07 0x2b6849ab 0xbeb40 0xbca88 0x85c173 0x864d67 0x85ea61 0x866b09 0x867e19 0x39782dc1 0x39782b14) libc++abi.dylib: terminating with uncaught exception of type NSException

Mon code:

class CameraViewController: UIViewController, CameraDelegate, AVCaptureFileOutputRecordingDelegate { 

    // MARK: 
    // MARK: - Property 
    @IBOutlet weak var captureButton: UIButton! 
    @IBOutlet var previewView: CameraPreviewView! 

    weak var cameraDelegate: CameraDelegate? 

    var sessionQueue: dispatch_queue_t? 
    var captureSession: AVCaptureSession? 
    var stillImageOutput: AVCaptureStillImageOutput? 
    var videoDeviceInput: AVCaptureDeviceInput? 
    var movieFileOutput: AVCaptureMovieFileOutput? 

    var previewLayer: AVCaptureVideoPreviewLayer? 

    var deviceAuthorized: Bool = false 
    var backgroundRecordId: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid 
    var sessionRuningAndDeviceAuthorized: Bool { 
     get { 
      return (self.captureSession?.running != nil && self.deviceAuthorized) 
     } 
    } 
    var runtimeErrorHandlingObserver: AnyObject? 
... 
} 

Ajout observateurs:

override func viewWillAppear(animated: Bool) { 
     super.viewWillAppear(animated) 

     dispatch_async(self.sessionQueue!, { 
      // TODO: Make constants 
      self.addObserver(self, forKeyPath: "sessionRunningAndDeviceAuthorized", options: NSKeyValueObservingOptions.Old | NSKeyValueObservingOptions.New, context: &SessionRunningAndDeviceAuthorizedContext) 
      self.addObserver(self, forKeyPath: "stillImageOutput.capturingStillImage", options: NSKeyValueObservingOptions.Old | NSKeyValueObservingOptions.New, context: &CapturingStillImageContext) 
      self.addObserver(self, forKeyPath: "movieFileOutput.recording", options: NSKeyValueObservingOptions.Old | NSKeyValueObservingOptions.New, context: &RecordingContext) 


      NSNotificationCenter.defaultCenter().addObserver(self, selector: "subjectAreaDidChange:", name: AVCaptureDeviceSubjectAreaDidChangeNotification, object: self.videoDeviceInput?.device) 

      weak var weakSelf = self 

      self.runtimeErrorHandlingObserver = NSNotificationCenter.defaultCenter().addObserverForName(AVCaptureSessionRuntimeErrorNotification, object: self.captureSession, queue: nil, usingBlock: { 
       (note: NSNotification?) in 
       var stronSelf: CameraViewController = weakSelf! 
       dispatch_async(stronSelf.sessionQueue!, { 
        if let sess = stronSelf.captureSession { 
         sess.startRunning() 
        } 
       }) 

      }) 

      self.captureSession?.startRunning() 
     })          
    } 

et le code avec la suppression des observateurs:

override func viewWillDisappear(animated: Bool) { 
     super.viewWillDisappear(animated) 

     dispatch_async(self.sessionQueue!, { 

      if let sess = self.captureSession { 
       sess.stopRunning() 

       NSNotificationCenter.defaultCenter().removeObserver(self, name: AVCaptureDeviceSubjectAreaDidChangeNotification, object: self.videoDeviceInput?.device) 
       NSNotificationCenter.defaultCenter().removeObserver(self.runtimeErrorHandlingObserver!) 

       // TODO: Make constants 

       self.removeObserver(self, forKeyPath: "sessionRunningAndDeviceAuthorized", context: &SessionRunningAndDeviceAuthorizedContext) 
       self.removeObserver(self, forKeyPath: "stillImageOutput.capturingStillImage", context: &CapturingStillImageContext) 
       self.removeObserver(self, forKeyPath: "movieFileOutput.recording", context: &SessionRunningAndDeviceAuthorizedContext) 

      } 
     }) 
    } 

Répondre

1

Vous utilisez le mauvais contexte dans removeObserver(...)

Aussi, pourquoi vous supprimez les observateurs dans un bloc asynchrone?

+0

Avez-vous pu résoudre ce problème? –

+0

@EdwardPotter S'il ne l'était pas, il n'aurait pas marqué ma réponse comme acceptée. – JeremyP