It appears I am getting a Strong Reference Cycle when using the NotifcationCenter.
I am using NotificationCenter to observe the Rotation of the device. (While some would argue this is not the best way to determine the device rotation, this currently seems to be my only route, as no autolayout is being used and storyboard is not being used).
deinit {}
is never being called in my ViewController
even if I remove the observer in viewWillDisappear
and viewDidDisappear
.
import UIKit
class TestVC: UIViewController {
deinit {
print("TestClass Deinit") //not being triggered ever
}
@objc private func rotationDetected(sender: Any) {
print("we rotated")
}
override func viewDidDisappear(_ animated: Bool) {
//NotificationCenter.default.removeObserver(UIDevice.orientationDidChangeNotification)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(UIDevice.orientationDidChangeNotification)
//NotificationCenter.default.removeObserver(self) //also doesn't work
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main, using: rotationDetected)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Any ideas as to why this is occurring and how to resolve it?
Also open to any new ideas on how to determine rotation detection else ways (no autolayout or storyboard is being used though).
To reach TestVC()
I used self.navigationController?.pushViewController(TestVC(), animated: true)
in the previous ViewController
and to go back I use the pop
.
Without the Observer
present, the class will correctly deinit
.
RESOLVED
Thanks to the answer marked below the Strong Reference Cycle is removed.
Simply replace NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main, using: rotationDetected)
with
NotificationCenter.default.addObserver(self, selector: #selector(rotationDetected), name: UIDevice.orientationDidChangeNotification, object: nil)
This should work in viewWillDisappear
:
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
in combination with using the following in viewWillAppear
:
NotificationCenter.default.addObserver(self, selector: #selector(rotationDetected), name: UIDevice.orientationDidChangeNotification, object: nil)