简体   繁体   English

Swift-通知观察者被多次调用

[英]Swift - notification observer is called several times

I have viewController and inside in viewDidLoad I have 我有viewController并且在viewDidLoad中有

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

In another controller I have 在另一个控制器中

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

If I go home from app and launch it again function showNextQuestionID fires two times. 如果我从应用程序回家然后再次启动它,则功能showNextQuestionID将触发两次。

I tried to use 我尝试使用

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

But this doesn't help, 但这无济于事

and in viewController 并在viewController中

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

How can I fix this ? 我怎样才能解决这个问题 ?

You are not removing your notification observer in the right place. 您没有在正确的位置删除通知观察者。 You register the observer in your view controller subclass, and you need to remove it in the same class. 您在视图控制器子类中注册了观察者,并且需要在同一类中将其删除。 A logical place is to override the viewWillDisappear method. 逻辑上的位置是重写viewWillDisappear方法。 Place the following code in your view controller subclass: 将以下代码放入您的视图控制器子类中:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NSNotificationCenter.defaultCenter().removeObserver(self)
}

Also remove 同时删除

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

From your AppDelegate. 从您的AppDelegate。 When you supply the 'self' argument in the AppDelegate, it is referring to the AppDelegate class, not your view controller. 当您在AppDelegate中提供'self'参数时,它是指AppDelegate类,而不是您的视图控制器。 When you call to remove your notification observer in the view controller sublcass, self is your view controller, which is what you want. 当您调用以删除视图控制器子目录中的通知观察器时,self是您的视图控制器,这就是您想要的。

Last, when you call simply removeObserver(self) with no other arguments, it will unregister all the observers for that object. 最后,当您仅调用removeObserver(self)而没有其他参数时,它将注销该对象的所有观察者。 That way you don't have to go through and list each observer by name. 这样,您就不必遍历并按名称列出每个观察者。

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

applicationDidEnterBackground and deinit should be ok. applicationDidEnterBackgrounddeinit应该可以。

The problem is the way you are trying to remove the observer in applicationDidEnterBackground . 问题是您尝试在applicationDidEnterBackground删除观察者的方式。 You are trying to remove the observer from AppDelegate and you need to remove the observer from your ViewController. 您正在尝试从AppDelegate中移除观察者,并且需要从ViewController中移除观察者。

To fix the problem: 解决问题:

1) Listen for UIApplicationDidEnterBackgroundNotification in your view controller: 1)在您的视图控制器中监听UIApplicationDidEnterBackgroundNotification:

func init() {
  super.init()

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

2) Implement the method that listen to UIApplicationDidEnterBackgroundNotification 2)实现监听UIApplicationDidEnterBackgroundNotification的方法

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

3) Extra. 3)额外。 You could also listen for UIApplicationWillEnterForegroundNotification in order to add again your custom notification 您也可以监听UIApplicationWillEnterForegroundNotification以便再次添加自定义通知

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM