通知观察者被多次调用,即使观察者被移除
Notification observer called multiple times even though the observer is removed
当应用程序处于后台模式或 phone 处于睡眠状态并且收到 VoIp 推送时,AppDelagte 中的以下功能将引导用户(到应用程序中的 UserTableViewController
)并发布一条通知。
UserTableViewController
的 viewDidLoad 中的通知观察者观察通知并调用 func simulateMyIncomingCallFromNotification
。
我注意到,当我第二次发送 VoIP 推送时,func simulateMyIncomingCallFromNotification
被调用两次,第三次,三次,依此类推。如何避免多次调用?
其他 SO 答案,建议删除 Notification observer,我什至在设置一个之前就这样做了,正如您在下面的扩展中看到的那样,但这似乎并没有解决我的问题。
我该如何解决这个问题?
在 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)
}
Apple 建议观察者应在 viewWillAppear
中注册并在 viewWillDissapear
中注销。
你能不能这样试试
多次调用通知可能是因为您的控制器没有被取消初始化,并且每次您向该控制器的新实例添加一个新的观察者。
你可以做什么:
在该方法上添加断点并尝试print(self)
并查看多次调用的地址。
或直接添加
deinit() {
print(self)
}
并检查 class 是否正在取消初始化。
如果不是这样,您可以尝试@ 解决方案。
在我的例子中,Notification
调用了 次 我出现在同一个屏幕上,并且触发了 相同的操作 X 进入屏幕的次数。所以我删除了 viewWillDisappear
中的 Notification
观察者,它实际上是有效的,并且 停止了在同一屏幕 action/methods 中多次触发 .
感谢 的回答,我明白了
- Swift4
addObserver
override func viewDidLoad(){
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.yourNotificationAction(notification:)), name: Notification.Name("yourNotificationName"), object: nil)
}
removeObserver
when screen is disappear
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: Notification.Name("yourNotificationName"), object: nil)
}
当应用程序处于后台模式或 phone 处于睡眠状态并且收到 VoIp 推送时,AppDelagte 中的以下功能将引导用户(到应用程序中的 UserTableViewController
)并发布一条通知。
UserTableViewController
的 viewDidLoad 中的通知观察者观察通知并调用 func simulateMyIncomingCallFromNotification
。
我注意到,当我第二次发送 VoIP 推送时,func simulateMyIncomingCallFromNotification
被调用两次,第三次,三次,依此类推。如何避免多次调用?
其他 SO 答案,建议删除 Notification observer,我什至在设置一个之前就这样做了,正如您在下面的扩展中看到的那样,但这似乎并没有解决我的问题。
我该如何解决这个问题?
在 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)
}
Apple 建议观察者应在 viewWillAppear
中注册并在 viewWillDissapear
中注销。
你能不能这样试试
多次调用通知可能是因为您的控制器没有被取消初始化,并且每次您向该控制器的新实例添加一个新的观察者。 你可以做什么:
在该方法上添加断点并尝试print(self)
并查看多次调用的地址。
或直接添加
deinit() {
print(self)
}
并检查 class 是否正在取消初始化。
如果不是这样,您可以尝试@
在我的例子中,Notification
调用了 次 我出现在同一个屏幕上,并且触发了 相同的操作 X 进入屏幕的次数。所以我删除了 viewWillDisappear
中的 Notification
观察者,它实际上是有效的,并且 停止了在同一屏幕 action/methods 中多次触发 .
感谢
- Swift4
addObserver
override func viewDidLoad(){
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.yourNotificationAction(notification:)), name: Notification.Name("yourNotificationName"), object: nil)
}
removeObserver
when screen is disappear
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: Notification.Name("yourNotificationName"), object: nil)
}