【问题标题】:Swift - notification observer is called several timesSwift - 多次调用通知观察者
【发布时间】:2015-08-18 15:50:07
【问题描述】:

我有 viewController 和里面的 viewDidLoad 我有

NSNotificationCenter.defaultCenter().addObserver(self, selector: "showNextQuestions", name: "showNextQuestionsID", object: nil)

在另一个控制器中我有

NSNotificationCenter.defaultCenter().postNotificationName("showNextQuestionsID", object: nil)

如果我从应用程序回家并再次启动它,函数 showNextQuestionID 会触发两次。

我尝试使用

func applicationDidEnterBackground(application: UIApplication) {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: "showNextQuestionsID", object: nil)
}

但这无济于事,

在视图控制器中

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

我该如何解决这个问题?

【问题讨论】:

    标签: ios swift nsnotificationcenter


    【解决方案1】:

    您没有在正确的位置删除通知观察者。您在视图控制器子类中注册了观察者,并且需要在同一个类中将其删除。一个合乎逻辑的地方是重写 viewWillDisappear 方法。将以下代码放在您的视图控制器子类中:

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    

    同时删除

     NSNotificationCenter.defaultCenter().removeObserver(self, name: "showNextQuestionsID", object: nil)
    

    来自您的 AppDelegate。当您在 AppDelegate 中提供“self”参数时,它指的是 AppDelegate 类,而不是您的视图控制器。当您调用删除视图控制器子类中的通知观察者时,self 是您的视图控制器,这就是您想要的。

    最后,当您只调用 removeObserver(self) 而不使用其他参数时,它将取消注册该对象的所有观察者。这样你就不必遍历并按名称列出每个观察者。

    【讨论】:

    • 还有其他方法不是 viewWillDisappear 吗?我需要更改 ViewController 中的 UI,而用户在另一个控制器上时注册了观察者。必须在用户到达这里之前更改控制器
    【解决方案2】:

    将您的观察者放在 AppDelegate 或单例中,以便您可以在应用程序状态期间轻松添加和删除观察者。

    【讨论】:

      【解决方案3】:

      applicationDidEnterBackgrounddeinit 应该没问题。

      问题在于您尝试删除applicationDidEnterBackground 中的观察者的方式。您正在尝试从 AppDelegate 中删除观察者,并且需要从 ViewController 中删除观察者。

      解决问题:

      1) 在视图控制器中监听 UIApplicationDidEnterBackgroundNotification:

      func init() {
        super.init()
      
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "myAppDidEnterBackground", name: UIApplicationDidEnterBackgroundNotification, object: nil) 
      }
      

      2) 实现监听UIApplicationDidEnterBackgroundNotification的方法

      func myAppDidEnterBackground() {
      NSNotificationCenter.defaultCenter().removeObserver(self, name: "showNextQuestionsID", object: nil)
      }
      

      3) 额外。您还可以收听 UIApplicationWillEnterForegroundNotification 以再次添加您的自定义通知

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-23
        • 1970-01-01
        相关资源
        最近更新 更多