I have a UIView similar to the one you can see below:
class ViewTaskViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
subscribeToNotifications()
}
func subscribeToNotifications() {
let notification = NotificationCenter.default
notification.addObserver(forName: Notification.Name(rawValue: "TimerUpdated"), object: nil, queue: nil, using: handleUpdateTimer)
print("Subscribed to NotificationCenter in ViewTaskViewController")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("TUFU TUFU TUFU")
NotificationCenter.default.removeObserver(self)
}
deinit {
print("DENINT")
}
@objc func handleUpdateTimer(notification: Notification) {
if let userInfo = notification.userInfo, let timeInSeconds = userInfo["timeInSeconds"] as? Int {
withUnsafePointer(to: &self.view) {
print("We got timeeeeee \(timeInSeconds) \($0)")
}
//do something here....
}
}
}
The issue I am having is that I am unable to remove the observers from this particular UIView when the user hits the back button and returns to another viewController.
ViewWillDisppear
is called but deinit
is not called. The strange thing is that if we remove subscribeToNotifications()
from viewDidLoad()
then the deinit
is called.
The other issue is related to a memory leak. As you can see in the screenshot below, when the view does subscribe to notifications and the user leaves/re-enters the view, the memory usage increase.
Now compare that to when the subscribeToNotifications()
is commented out, there is no increase in memory usage and only one instance of the viewController.
The conclusion is that there seems to be a correlation between the notification subscription creation of a new instance of the UIView hence the deinit
is not being called.
I'd like to find out if there is a way we can deinitialize the view and unsubscribe from the notification.
Please let me know if you need further information. :)
I've found the removeObserver() only works if you use this version of addObserver()
notification.addObserver(self, selector:#selector(self.handleUpdateTimer), name: Notification.Name(rawValue: "TimerUpdated"), object: nil)
I'm guessing with the original version you aren't actually indicating who the observer is.
As @Spads said you can use
NotificationCenter.default.addObserver(self, selector: #selector(subscribeToNotifications), name: NSNotification.Name(rawValue: "TimerUpdate"), object: nil)
or the one you already have. you can remove your notification by it's name or it's reference
NotificationCenter.default.removeObserver(self, name: "TimerUpdate", object: nil)
if you declared your notification at the top of your class then you can directly pass the reference of your notification to be removed in your case notification
NotificationCenter.default.removeObserver(notification)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With