SwiftUI:在运行时访问EnvironmentObject access时出现线程错误

SwiftUI:在运行时访问EnvironmentObject access时出现线程错误,swiftui,swiftui-environment,Swiftui,Swiftui Environment,我有一个场景,有几个环境对象: func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Get the managed object context from the shared persistent container. let context = (UIApplication.s

我有一个场景,有几个环境对象:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Get the managed object context from the shared persistent container.
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
    // Add `@Environment(\.managedObjectContext)` in the views that will need the context.
    let contentView = MainTabView()
        //Inject Database repository
        .environmentObject(DatabaseRepository())
        .environmentObject(UserRepository())
        .environmentObject(StockRepository(api: AlphaVantageAPI()))
        .environment(\.managedObjectContext, context)
    // Use a UIHostingController as window root view controller.
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)            
        window.rootViewController = UIHostingController(rootView: contentView)
        self.window = window
        window.makeKeyAndVisible()
    }
}
在我的MainTabView中,我创建了如下选项卡:

struct MainTabView: View {
    @EnvironmentObject var database: DatabaseRepository
    @EnvironmentObject var userRepository: UserRepository
    @EnvironmentObject var stockRepository: StockRepository
    var viewModel = MainTabViewModel()
    init() {
        UITabBar.appearance().barTintColor = UIColor(named: "primary")
    }
    var body: some View {
        TabView {
            HomeView(viewModel: HomeViewModel(databaseRepository: database,
                                              userRepository: userRepository,
                                              stockRepository: stockRepository))
                .tabItem {
                    Image("account_balance_wallet")
                        .renderingMode(.template)
                    Text("Home")
                }.tag(0)
            ...
        }.accentColor(.white)
    }
}
在我的HomeVM中,我有以下代码:

class HomeViewModel: ObservableObject {
    @Published var watchingVMs = [EquityPreviewCellViewModel]()
    

    private let databaseRepository: DatabaseRepositoryProtocol
    private let userRepository: UserRepositoryProtocol
    private let stockRepository: StockRepositoryProtocol
    

    init(databaseRepository: DatabaseRepositoryProtocol,
         userRepository: UserRepositoryProtocol,
         stockRepository: StockRepositoryProtocol) {
        self.databaseRepository = databaseRepository
        self.userRepository = userRepository
        self.stockRepository = stockRepository
        self.bind()
    }
    func bind() {
        let allorders = databaseRepository
            .allOrder(userID: userRepository.userID).share()
        allorders
            .assertNoFailure()
            .compactMap({orders in
                return orders?.reduce([Order](), { finalOrders, nextOrder in
                    var orders = [Order](finalOrders)
                    if !finalOrders.contains(where: { $0.symbol == nextOrder.symbol }) {
                        orders.append(nextOrder)
                    }
                    return orders
                }).map({EquityPreviewCellViewModel(order: $0,
                                                   stockRepository: self.stockRepository,
                                                   userRepository: self.userRepository,
                                                   dataBaseRepository: self.databaseRepository)})
            })
            .receive(on: DispatchQueue.main)
            .assign(to: &self.$watchingVMs)
我启动我的应用程序时发生以下崩溃:

线程1:EXC_BAD_指令(代码=EXC_I386_INVOP,子代码=0x0)

我想我没有很好地使用
环境对象
,但我不明白为什么。

可能是您想要的

.assign(to: \.watchingVMs, on: self)
或者(使用弱自我)

更新:将本地
allorders
移动到属性以保持引用活动

func bind() {
    let allorders = databaseRepository
        .allOrder(userID: userRepository.userID).share()
    allorders    // << this one is destroyed on quit from bind
func bind(){
让allorders=databaseRepository
.allOrder(userID:userRepository.userID).share()

allorders/我认为您可能需要将此添加到
main选项卡视图中

@Environment(\.managedObjectContext) var managedObjectContext
因为我们使用环境修饰符进行设置,并且您可能在simple
@FetchRequest
s上执行保存、删除和其他一些任务

@Asperi建议的更改也是完全正确的,应该为此问题添加更改。这是因为方法签名不同:

.assign(to: \.watchingVMs, on: self)

也可能有线程问题导致
EXC_BAD_ACCESS
,可能值得在此检查同步问题,即在同一主队列上执行提取请求。

不,两者都会发生相同的崩溃。即使是空的接收器崩溃,请参阅更新的partEven move in属性也会使其仅在第一次运行时崩溃。我的解决方案是否有效?请告诉我。Fi最后,捕获失败的是我的
assertNoFailure
。最后,与环境对象无关。
.assign(to: \.watchingVMs, on: self)