NotifcationCenter вызывает сильный референсный цикл - Swift 5

Похоже, я получаю Strong Reference Cycle при использовании NotifcationCenter.

Я использую NotificationCenter для наблюдения за вращением устройства. (Хотя некоторые утверждают, что это не лучший способ определения ротации устройства, в настоящее время это, кажется, мой единственный маршрут, так как не используется автоматическое расположение и раскадровка не используется).

deinit {} никогда не вызывается в моем ViewController даже если я viewWillDisappear наблюдателя из viewWillDisappear и 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()
    }


}

Любые идеи относительно того, почему это происходит и как это решить?

Также открыты для любых новых идей о том, как определить обнаружение вращения другими способами (хотя не используется ни автопутевка, ни раскадровка).

Чтобы добраться до TestVC() я использовал self.navigationController?.pushViewController(TestVC(), animated: true) в предыдущем ViewController а для возврата я использую pop .

Без Observer класс будет правильно определен.

ПОСТАНОВИЛИ

Благодаря ответу, указанному ниже, Сильный ссылочный цикл удален.

Просто замените NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main, using: rotationDetected)

с

NotificationCenter.default.addObserver(self, selector: #selector(rotationDetected), name: UIDevice.orientationDidChangeNotification, object: nil)

Всего 2 ответа


Это должно работать в viewWillDisappear :

NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)

в сочетании с использованием следующего в viewWillAppear :

NotificationCenter.default.addObserver(self, selector: #selector(rotationDetected), name: UIDevice.orientationDidChangeNotification, object: nil)

Ваш метод удаления наблюдателя неверен, вы должны сделать так:

class TestVC {
    private var observer: Any

    func viewWillAppear() {
        observer = NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main, using: rotationDetected)
    }

    func viewWillDisappear() {
        NotificationCenter.default.removeObserver(observer)
    }
}

для устранения сильной ссылки цикла, используйте слабый замыканию.


Есть идеи?

10000