     }
     func
         deobserve(_ observee :Observee) {
+        guard self.isObserving else { return }
         for (keyPath, _) in self.keyPaths {
             observee.removeObserver(
                 self,
                 forKeyPath: keyPath
             )
         }
+        self.isObserving = false
     }
     func
         detach() {
-        if let observee = self.observeeBeingDeobserved() {
-            self.deobserve(observee)
-            self.observee = nil
-        }
+        let observee = self.observee
+        self.deobserve(observee)
     }
-    func
-        observeeBeingDeobserved() -> Observee? {
-        return self.observee
-    }
-    
+
     override func
         observeValue(
         forKeyPath keyPath: String?,

    weak var
    recorder: Reporting.Recorder? {
        willSet {
            guard let observee = self.observee else { return }
            if let _ = self.recorder {
                self.deobserve(observee)
            }
        }
        didSet {
            guard let observee = self.observee else { return }
            if let _ = self.recorder {
                self.observe(observee)
            }

    where Observee : NSObject
{
    let
    keyPaths :[String: NSKeyValueObservingOptions],
    observeeRef :NSValue
    var
    isObserving = false
    var
    observee :Observee {
        return self.observeeRef.nonretainedObjectValue as! Observee
    }
    init(
        keyPaths :[String: NSKeyValueObservingOptions],
        observee :Observee
        ) {
        self.keyPaths = keyPaths
        self.observeeRef = NSValue(nonretainedObject: observee)
    }
    deinit {
        self.detach()
    }
    func
        observe(_ observee :Observee) {
        guard self.isObserving == false else { return }
        self.isObserving = true
        for (keyPath, options) in self.keyPaths {
            observee.addObserver(
                self,
