1

使用通知中心时,我似乎得到了一个强参考周期。

我正在使用 NotificationCenter 来观察设备的旋转。(虽然有些人认为这不是确定设备旋转的最佳方式,但目前这似乎是我唯一的途径,因为没有使用自动布局,也没有使用情节提要)。

deinit {}ViewController即使我删除了 and 中的观察者,viewWillDisappear也永远不会在 my 中调用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现在,班级将正确deinit

解决

由于下面标记的答案,强参考循环被删除。

只需更换NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: .main, using: rotationDetected)

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

4

2 回答 2

1

这应该适用于viewWillDisappear

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

结合使用以下内容viewWillAppear

NotificationCenter.default.addObserver(self, selector: #selector(rotationDetected), name: UIDevice.orientationDidChangeNotification, object: nil)
于 2020-01-16T16:24:10.300 回答
0

您删除观察者的方法不正确,您应该这样做:

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)
    }
}

要消除强引用循环,请在闭包中使用弱。

于 2020-01-16T16:29:01.780 回答