This is my first post. I'm Japanese iOS engineer (just became this month).
I have a trouble with removeObserver
method of NotificationCenter
in Swift 5.
I added observer to ViewController (VC) by using closure type addObserver
.
I want to remove this Observer when VC's deinitialization has called.
I wrote NotificationCenter.default.removeObserver(self)
in VC's deinit
method. But, this seemed not to work for me.
What's the problem???
Additionally, if my code has memory leak problem, let me know how to fix it.
Here's piece of my code.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}
}
deinit {
print(#function)
print("ViewController died")
NotificationCenter.default.removeObserver(self)
}
}
Set your observer object to current view controller.
From apple doc.s, object is
The object whose notifications the observer wants to receive; that is, only notifications sent by this sender are delivered to the observer.
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification,
object: self,
queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}
Removing observer from NotificationCenter
deinit {
NotificationCenter.default.removeObserver(self)
}
ANOTHER WAY
You can also make copy of Notification Observer object and remove it from NotificationCenter
in deinit
.
let notificationCenter = NotificationCenter.default
var loadWeatherObserver: NSObjectProtocol?
override func viewDidLoad() {
super.viewDidLoad()
loadWeatherObserver = notificationCenter.addObserver(forName: UIApplication.didBecomeActiveNotification,
object: nil,
queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}
}
deinit {
if (loadWeatherObserver != nil) {
notificationCenter.removeObserver(loadWeatherObserver!)
}
}