iOS中Notification通知被重复调用两次问题求助
问题:通知触发后模块回调被执行两次的排查与解决
可能的原因及对应解决办法
1. 观察者移除逻辑未生效
你调用的SweeprClient.removeNotificationObservers()可能没有正确移除当前实例的通知观察者,比如该方法的实现是移除SweeprClient单例自身的观察者,而非调用setupLiveCycleNotifications的那个self对象。
解决办法:
替换原有的移除调用,直接针对当前实例移除对应通知的观察者:
func setupLiveCycleNotifications() { // 替换SweeprClient.removeNotificationObservers()为以下代码 NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(appMovedToForeground), name: UIApplication.didBecomeActiveNotification, object: nil) }
2. 类实例被重复创建
即使你确认setupLiveCycleNotifications只执行一次,也可能存在多个类实例的情况——每个实例都会添加一组观察者,导致通知触发时多个实例的回调方法被执行,进而多次发送事件到session模块。
解决办法:
在setupLiveCycleNotifications中添加实例地址打印,确认是否为同一实例:
func setupLiveCycleNotifications() { print("当前实例地址:", Unmanaged.passUnretained(self).toOpaque()) // ... 原有代码 }
如果打印出多个不同地址,检查测试代码或初始化逻辑,确保只创建一个目标类实例。
3. 订阅被重复添加
测试代码中如果存在多次订阅同一事件的情况(比如测试的setup方法中也做了订阅),会导致同一事件触发多个回调。
解决办法:
给测试订阅添加唯一标识tag,并在测试结束后取消订阅:
let testTag = "test_lifecycle_unique_tag" let backgroundExpectation = self.expectation(description: "background expectation") let foregroundExpectation = self.expectation(description: "foreground expectation") Client.modules!.subscribe(module: "session", event: SessionProvider.Events.application_lifecycle.rawValue, tag: testTag) { result, tag in if result == "background" { backgroundExpectation.fulfill() } if result == "foreground" { foregroundExpectation.fulfill() } } // 测试结束后取消订阅,避免影响其他测试 defer { Client.modules!.unsubscribe(module: "session", event: SessionProvider.Events.application_lifecycle.rawValue, tag: testTag) } // ... 原有通知发送和等待逻辑
4. 生命周期回调方法重复发送事件
检查appMovedToBackground和appMovedToForeground的实现,确认是否在方法内重复调用了模块事件发布的代码,比如:
@objc func appMovedToBackground() { // 若此处存在两次publish调用,会导致回调触发两次 Client.modules?.publish(module: "session", event: SessionProvider.Events.application_lifecycle.rawValue, data: "background") Client.modules?.publish(module: "session", event: SessionProvider.Events.application_lifecycle.rawValue, data: "background") }
如果是这种情况,删除重复的发布代码即可。
内容的提问来源于stack exchange,提问作者Kouv
相关产品推荐
相关产品推荐

