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

为何LoginDateMonitorView会在调试器中产生大量日志信息?

问题原因分析:LoginDateMonitorView触发大量调试日志

核心问题

调试器中反复出现的[SwiftUI] 不允许在视图更新过程中发布变更,这将导致未定义行为日志,根源在于你对ObservableObject的objectWillChange实现不符合SwiftUI的规范要求。

具体触发原因

  1. objectWillChange类型不匹配
    ObservableObject协议要求objectWillChange发送的是Void类型的信号(用于告知SwiftUI对象即将变更),但你在PropertyObserver扩展中返回的是AnyPublisher<Value, Never>,也就是直接发送了属性的具体值,而非符合要求的空信号。

  2. 循环更新闭环
    当User的lastLogin变化时,自定义发布者发送Date值触发视图更新,但视图更新过程中又会意外触发发布者再次发送信号,形成循环触发,最终导致数百条警告日志输出。

修复方案

修改PropertyObserver扩展中的objectWillChange实现,将属性值信号转换为符合要求的Void信号:

extension PropertyObserver {
    var objectWillChange: AnyPublisher<Void, Never> {
        object.publisher(for: property)
            .map { _ in () } // 将属性值转换为空信号
            .eraseToAnyPublisher()
    }
}

如果需要更严谨的内存管理(避免内存泄漏),可以结合关联对象存储订阅:

extension PropertyObserver {
    var objectWillChange: ObservableObjectPublisher {
        let publisher = ObservableObjectPublisher()
        object.publisher(for: property)
            .sink { _ in
                publisher.send()
            }
            .store(in: &cancellables)
        return publisher
    }
    
    private var cancellables: Set<AnyCancellable> {
        get {
            (objc_getAssociatedObject(self, &cancellablesKey) as? Set<AnyCancellable>) ?? .init()
        }
        set {
            objc_setAssociatedObject(self, &cancellablesKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

private var cancellablesKey = 0

补充说明

ObservableObject的objectWillChange本质是一个"通知开关",只需要告诉SwiftUI「对象要变了,准备更新视图」即可,不需要传递具体的属性值。原实现的信号类型错误,打乱了SwiftUI的更新逻辑,从而触发了循环警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 15:35:20