     }
 
     deinit {
-        if containerView != nil {
-            containerView.superview?.removeObserver(self, forKeyPath: TorchContentOffsetKey)
-            containerView.superview?.removeObserver(self, forKeyPath: TorchContentSizetKey)
-        }
+        observingContentSizeToken?.invalidate()
+        observingContentOffsetToken?.invalidate()
     }
 
     func stopObserving() {
-        scrollView.removeObserver(self, forKeyPath: TorchContentOffsetKey)
-        if !isPullingDown {
-            scrollView.removeObserver(self, forKeyPath: TorchContentSizetKey)
-        }
+        observingContentSizeToken?.invalidate()
+        observingContentOffsetToken?.invalidate()
     }
 
     func startObserving() {


import UIKit

private var TorchContentOffsetKVOContext = 0
private var TorchContentSizeKVOContext = 1
private let TorchContentOffsetKey = "contentOffset"
private let TorchContentSizetKey = "contentSize"

open class PullObserver: NSObject {
    let option: PullOption
    weak var refreshView: RefreshView!

            fatalError("Refreher can only be used in UIScrollView and it's subclasses.")
        }

        observingContentOffsetToken = scrollView.observe(\.contentOffset,
                                                         options: .new) { [weak self] (_, _) in
            guard let strongSelf = self else { return }
            strongSelf.observingContentOffsetChanges()
        }

        originalContentOffsetY = scrollView.contentOffset.y

        if !isPullingDown {
            observingContentSizeToken = scrollView.observe(\.contentSize,
                                                           options: .new) { [weak self] (_, _) in
                guard let strongSelf = self else { return }
                strongSelf.observingContentSizeChanges()
            }
        }
    }

