从不同 ViewController 移除 NSNotification 观察者

Removing NSNotificationObserver From Different ViewController

我有一个观察员,我在一个 class 中注册为:

class ViewControllerA: UIViewController {

//create shared class reference
var sharedClassReference_A = SharedClass()


//initialize Notification Observer and store observer reference in sharedClass
override func viewDidLoad() {
    super.viewDidLoad()

    var observerHandler: Any? = nil

    observerHandler = NotificationCenter.default.addObserver(self, selector: #selector(ViewControllerA.appDidTerminate(_:)), name: .UIApplicationWillTerminate, object: nil)

    self.sharedClassReference_A.sharedHandler = observerHandler

}

//perform some action when a notification is received
@objc func appDidTerminate(_ notification: NSNotification) {

    //perform some action

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueA_X" {
        let destinationController = segue.destination as! ViewControllerX
       destinationController.sharedClassReference_X = self.sharedClassReference_A
    }
}

}

我在共享 class 中存储了对观察者的引用:

class SharedClass {

var sharedHandler: Any? = nil

}

我尝试在到达不同的视图控制器后删除观察者:

class ViewControllerX: UIViewController {

var sharedClassReference_X = SharedClass()

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

    //Attempt to remove observer registered in ViewControllerA
    if let observerHandler = self.sharedClassReference_X.sharedHandler {
         NotificationCenter.default.removeObserver(observerHandler)
    }
}

}

我知道使用这种方法删除观察者是失败的,因为在释放 ViewControllerX 之后调用观察者。

我的问题是:我如何才能在一个 class (ViewControllerA) 中成功初始化一个观察者并能够稍后在另一个 class (ViewControllerX) 中将其删除?

我认为最好遵循在 viewDidLoad/viewWillAppear 中设置观察者并根据您的情况分别在 deinit / viewDidDisappear 中删除它们的一般准则, 因为这个

NotificationCenter.default.addObserver(self, selector: #selector(ViewControllerA.appDidTerminate(_:)), name: .UIApplicationWillTerminate, object: nil)

returns 无效

//

class ViewControllerX: UIViewController { 
   var aRef:ViewControllerA!
}

在 prepareForSegue

destinationController.aRef = self

然后使用

NotificationCenter.default.removeObserver(aRef, name: NSNotification.Name.UIApplicationWillTerminate, object: nil)