【问题标题】:Where is the right place to remove notification observers in Swift 2?在 Swift 2 中删除通知观察者的正确位置在哪里?
【发布时间】:2016-12-12 17:00:41
【问题描述】:

我有这个代码,取自这个答案:https://stackoverflow.com/a/29099066/406322

extension NSNotificationCenter {
    func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
        NSNotificationCenter.defaultCenter().removeObserver(observer, name: name, object: object)
        NSNotificationCenter.defaultCenter().addObserver(observer, selector: selector, name: name, object: object)
    }
}

现在,在我的视图控制器中,我在 viewDidLoad() 中设置我的观察者:

override func viewDidLoad() {
        super.viewDidLoad()
        setObservers()
}

func setObservers() {
        NSNotificationCenter.defaultCenter().setObserver(self, selector: #selector(BaseController.handleComment(_:)), name: "newComment", object: nil)
}

然而,即使使用这个扩展,观察者在被添加之前被移除,每次我退出视图控制器并返回它时,我都会收到多个通知(每次多一个)。

这怎么可能?

【问题讨论】:

  • 你确定旧的视图控制器正在被释放吗?额外的通知很可能会发送到视图控制器的先前实例。
  • 我该如何释放它们,对不起这里是 Swift 的初学者。

标签: swift swift2 nsnotificationcenter


【解决方案1】:

如果你需要这个setObserver 扩展,你很可能做错了什么。您应该能够轻松地平衡您的注册和删除。如果不能,您的通知管理很可能过于复杂或位置错误。

通常添加观察的正确位置是在viewWillAppear(或viewDidAppear,两者都可以),并在viewDidDisappear(或viewWillDisappear)中删除它们。这可以确保您在屏幕外时不会收到通知,即使视图控制器仍然存在(这很常见)。

如果您的视图控制器要求它在屏幕外时接收通知,那么您有一个设计问题。视图控制器应该只管理屏幕视图。如果他们正在做其他事情,那么您将太多的模型放入控制器中。

正如@rmaddy 所指出的,您的具体问题可能是您有此视图控制器的两个实例。这可能很好,也可能是一个错误(这取决于视图控制器的工作方式)。但是,如果您在屏幕上和屏幕外时平衡添加和删除注册,那部分就可以了。

【讨论】:

  • 谢谢,说得有道理,将尝试将它们移动到 viewWillAppear/viewWillDisappear。由于我是 Swift 的新手,我试图理解,如何可能有两个 ViewController 实例。在我的情况下,我在这个视图控制器上有一个关闭按钮,它执行这个 navigationController?.popViewControllerAnimated(true),然后在父视图中,有一个按钮可以返回到这个视图控制器。这可能是原因吗?这是糟糕的设计吗?每次弹出时我是否应该释放一些东西?
  • 是的,将它们移动到 viewWillAppear 解决了这个问题。
  • 请记住,额外的视图控制器可能仍然存在问题。验证关闭视图控制器时是否正在调用 deinit
  • 你的 segue 方案听起来不错。我希望某处有一个保留循环会泄漏您的视图控制器。类似于重复的 NSTimer(视图控制器上保持循环的常见原因)或强烈捕获 self 的闭包。
  • 我的控制器中有一个计时器,并且在这个视图控制器的闭包中有一些“自我”引用。这不是好习惯吗?我应该将它们全部转换为弱自我吗?
猜你喜欢
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多