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
相关产品推荐
相关产品推荐

