You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:33:12