即使已经移除了观察者,通知观察者仍然被多次调用

3
当应用程序在后台模式或手机处于睡眠状态且接收到VoIP推送时,AppDelagte中的以下函数将指示用户前往应用程序中的UserTableViewController,并发布通知。
在UserTableViewController的viewDidLoad中,通知观察器观察通知并调用simulateMyIncomingCallFromNotification函数。
我注意到当我第二次发送VoIP推送时,simulateMyIncomingCallFromNotification函数会被调用两次,第三次会调用三次,依此类推。如何避免多次调用?
其他SO答案建议删除通知观察器,但是我甚至在设置通知观察器之前就已经这样做了,如下所示的扩展,但似乎无法解决我的问题。
我该如何解决这个问题?
在AppDelegate中:
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

 let storyboard = UIStoryboard(name: "User", bundle: nil)

 VC = storyboard.instantiateViewController(withIdentifier: "UserTableViewController") as! UserTableViewController

 self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = VC
        self.window?.makeKeyAndVisible()


NotificationCenter.default.post(name: Notification.Name("didReceiveIncomingVoipPush"), object: nil, userInfo: payloadDict)
}

在UserTableViewController中
extension NotificationCenter {
    func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
        print("NotificationCenter.default before: \(NotificationCenter.default)")
        NotificationCenter.default.removeObserver(observer, name: name, object: object)
        NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object)
        print("NotificationCenter.default after: \(NotificationCenter.default)")
    }
}

fun viewDidLoad(){

NotificationCenter.default.setObserver(self, selector: #selector(self.simulateMyIncomingCallFromNotification(notification:)), name: Notification.Name("didReceiveIncomingVoipPush"), object: nil)

}

感谢您使用“即使”从句提出问题。非常准确 :) - Oded Ben Dov
3个回答

10

苹果建议观察者应该在viewWillAppear中注册,并在viewWillDissapear中取消注册。

你可以试试这样做。


2

如果您收到了多个通知电话,很可能是因为您的控制器没有被取消初始化,每次都向该控制器的新实例添加新的观察者。您可以执行以下操作:

在该方法上添加断点,尝试使用print(self)查看多个调用的地址。

或者只需添加

 deinit() {
    print(self)
 }

检查该类是否正在被销毁。

如果不是这种情况,您可以尝试@Himanth的解决方案。


在哪个方法上添加断点或deinit()? - SpaceX
被多次调用的方法 simulateMyIncomingCallFromNotification - ankit

2
在我的情况下,Notification 调用了出现次数,而这是由于触发了相同操作 X 我进入屏幕的次数。因此,我在viewWillDisappear中删除了Notification观察者,这实际上起到了作用,并停止了在同一屏幕上多次触发的操作/方法
感谢Himanth的答案,我找到了解决方法。
  • Swift4

addObserver

 override func viewDidLoad(){
       super.viewDidLoad()

      NotificationCenter.default.addObserver(self, selector: #selector(self.yourNotificationAction(notification:)), name: Notification.Name("yourNotificationName"), object: nil)

}

当屏幕消失时,需要使用removeObserver
 override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        NotificationCenter.default.removeObserver(self, name: Notification.Name("yourNotificationName"), object: nil)
      
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接