I have an observer that I register in one class as so:
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
}
}
}
I store a reference to the observer in a shared class:
class SharedClass {
var sharedHandler: Any? = nil
}
I attempt to remove the observer once I reach a different view controller as so:
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)
}
}
}
I know that removing the observer using this approach is failing, because the observer is getting called after ViewControllerX is deallocated.
My question is: How can I successfully initialize an observer in one class (ViewControllerA) and be able to remove it later in a different class (ViewControllerX)?
I think it's better to follow the general guidelines of setting the observers inside viewDidLoad
/viewWillAppear
and removing them inside deinit
/ viewDidDisappear
respectively according to your case , as this
NotificationCenter.default.addObserver(self, selector: #selector(ViewControllerA.appDidTerminate(_:)), name: .UIApplicationWillTerminate, object: nil)
returns void
//
class ViewControllerX: UIViewController {
var aRef:ViewControllerA!
}
in prepareForSegue
destinationController.aRef = self
Then use
NotificationCenter.default.removeObserver(aRef, name: NSNotification.Name.UIApplicationWillTerminate, object: nil)