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

SwiftUI中使用Sub Interactor报错:无法生成表达式诊断

解决通过Interactor传递@Published变量时的"Failed to produce diagnostic"错误

问题场景

我创建了包含@Published变量的SubInteractor,MainInteractor依赖该子Interactor,MainView持有MainInteractor,需要通过MainInteractor将子Interactor的@Published变量传递给子视图,但编译时出现错误:

Failed to produce diagnostic for expression; please submit a bug report...

相关代码

SubInteractor

import Combine

class SubInteractor {
    @Published var count: Int = 0
    
    func incrementCount() {
        count += 1
    }
}

MainInteractor

class MainInteractor {
    let subInteractor: SubInteractor
    
    init(subInteractor: SubInteractor) {
        self.subInteractor = subInteractor
    }
    
    // 尝试暴露子Interactor的@Published属性
    var count: Int {
        subInteractor.count
    }
    
    // 尝试用Publisher转发
    var countPublisher: AnyPublisher<Int, Never> {
        subInteractor.$count.eraseToAnyPublisher()
    }
}

MainView

import SwiftUI

struct MainView: View {
    let mainInteractor: MainInteractor
    
    var body: some View {
        VStack {
            // 尝试直接传递,出现错误
            ChildView(count: mainInteractor.count)
            
            Button("Increment") {
                mainInteractor.subInteractor.incrementCount()
            }
        }
    }
}

struct ChildView: View {
    let count: Int
    
    var body: some View {
        Text("Count: \(count)")
    }
}

尝试过的修改方案

  • 直接在MainInteractor中暴露子Interactor的count属性作为计算属性
  • 在MainInteractor中创建countPublisher转发子Interactor的$count
  • 尝试在MainView中用@ObservedObject持有MainInteractor,再传递mainInteractor.subInteractor.count

解决建议

1. 让Interactor遵循ObservableObject协议

@Published属性只有在遵循ObservableObject的类中,才能被SwiftUI正确监听。修改两个Interactor:

class SubInteractor: ObservableObject {
    @Published var count: Int = 0
    
    func incrementCount() {
        count += 1
    }
}

class MainInteractor: ObservableObject {
    let subInteractor: SubInteractor
    private var cancellables = Set<AnyCancellable>()
    
    // 转发子Interactor的count变化到自身的@Published属性
    @Published var count: Int = 0
    
    init(subInteractor: SubInteractor) {
        self.subInteractor = subInteractor
        // 订阅子Interactor的count更新,同步到自身
        subInteractor.$count
            .assign(to: \.count, on: self)
            .store(in: &cancellables)
    }
    
    // 封装子Interactor的操作,避免View直接依赖子Interactor
    func incrementCount() {
        subInteractor.incrementCount()
    }
}

2. 在View中正确绑定ObservableObject

根据MainInteractor的创建时机选择@ObservedObject或@StateObject(外部传入用@ObservedObject,内部初始化用@StateObject),再传递属性给子视图:

struct MainView: View {
    @ObservedObject var mainInteractor: MainInteractor
    
    var body: some View {
        VStack {
            // 单向传递用普通属性
            ChildView(count: mainInteractor.count)
            Button("Increment") {
                mainInteractor.incrementCount()
            }
        }
    }
}

struct ChildView: View {
    let count: Int
    
    var body: some View {
        Text("Count: \(count)")
    }
}

如果需要双向绑定,子视图可以用@Binding接收:

struct MainView: View {
    @ObservedObject var mainInteractor: MainInteractor
    
    var body: some View {
        VStack {
            ChildView(count: $mainInteractor.count)
            Button("Increment") {
                mainInteractor.incrementCount()
            }
        }
    }
}

struct ChildView: View {
    @Binding var count: Int
    
    var body: some View {
        Text("Count: \(count)")
    }
}

错误原因分析

出现该编译错误的核心原因是:

  • 未让持有@Published属性的类遵循ObservableObject,导致SwiftUI无法识别监听逻辑
  • 跨层级传递未被正确包装的响应式属性,造成编译器类型推断冲突,无法生成视图更新的诊断信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:06:05