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

使用NWPathMonitor配合BehaviorSubject监控网络连通性出现重复触发问题

问题根因
  • 最高频触发原因是NetworkService单例实现错误:如果你的shared是计算属性而非静态存储属性,每次调用NetworkService.shared都会创建全新的NWPathMonitor实例,每个实例的回调都会独立触发事件,事件量会随实例数量增长快速堆积,最终导致应用崩溃。
  • 其次是线程安全问题:你的previousValue是普通存储属性,读写操作没有限定在同一队列,即使加了信号量也可能因为跨队列读写出现竞态,导致相等判断逻辑失效。
  • NWPathMonitor的pathUpdateHandler会在任意路径属性变化时触发,哪怕网络连通状态没有变化(比如WiFi切换到蜂窝网络、网络时延波动等),都会触发回调,如果没有过滤相同值,就会收到大量重复的连通状态事件。
  • 额外的代码问题:你的pathUpdateHandler没有加[weak self]修饰,会造成循环引用,也可能引发异常的事件回调。
修复方案

1. 修正单例与监听逻辑

确保NetworkService全局唯一,所有状态读写都在NWPathMonitor的回调串行队列执行(天然线程安全,不需要额外加信号量):

import Network
import RxSwift

class NetworkService {
    // 静态存储属性,全局唯一实例
    static let shared = NetworkService()
    private let monitor = NWPathMonitor()
    let connected = BehaviorSubject<Bool>(value: true)
    private var previousStatus: Bool = true
    // 私有初始化方法,禁止外部创建新实例
    private init() {
        let queue = DispatchQueue(label: "com.yourapp.NetworkMonitor")
        monitor.pathUpdateHandler = { [weak self] path in
            guard let self = self else { return }
            let currentStatus = path.status == .satisfied
            // 状态无变化直接跳过,所有读写都在当前串行队列执行,无竞态问题
            guard currentStatus != self.previousStatus else { return }
            self.previousStatus = currentStatus
            self.connected.onNext(currentStatus)
        }
        monitor.start(queue: queue)
    }
}

2. 订阅侧增加重复值过滤(推荐)

即使上游出现异常重复事件,也可以通过Rx内置操作符在订阅侧兜底过滤,需要操作UI的话务必切换到主队列:

NetworkService.shared.connected
    .distinctUntilChanged() // 过滤连续相同的事件
    .observe(on: MainScheduler.instance) // 涉及UI操作必须切到主队列
    .subscribe(onNext: { connected in
        print("network connected: \(connected)")
        // 你的业务逻辑
    })
    .disposed(by: disposeBag)

3. 冗余逻辑清理

你之前添加的信号量逻辑可以完全删除,NWPathMonitor的回调会在你传入的串行队列中串行执行,不会出现并发调用的情况,额外加信号量只会增加不必要的性能损耗甚至死锁风险。

内容的提问来源于stack exchange,提问作者Vahid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:45:03