简体   繁体   English

如何在辅助 Class 中正确处理 @EnvironmentObject

[英]How to correctly handle @EnvironmentObject within secondary Class

When using @EnvironmentObject, can you have an @EnvironmentObject inside of another class?使用@EnvironmentObject 时,您可以在另一个class 中使用@EnvironmentObject 吗?

I have a setup (MeetingStats) class and then a processing class(Meeting).我有一个设置(MeetingStats)class,然后是一个处理类(会议)。 The processing class and the setup classes are both displayed via different tabs in my app.处理 class 和设置类都通过我的应用程序中的不同选项卡显示。 So if you can change the settings in setup, you should see in real time the changes to the processing class (that is mostly timer driven).因此,如果您可以在 setup 中更改设置,您应该实时看到对处理 class(主要是定时器驱动)的更改。

I have tried to switch from using the AppDelegate to passing things between views, to using @EnvironmentObject.我试图从使用 AppDelegate 切换到在视图之间传递东西,再到使用 @EnvironmentObject。 I have changed my ScceneDelegate to create the initial objects, and am passing them.envrionmentObjects to the ContentView.我已更改我的 ScceneDelegate 以创建初始对象,并将它们传递给 ContentView。 However, when I run the app, the first time I try to access the setup class in the processing class, I crash with the message No ObservableObject of type MeetingStats found.但是,当我运行该应用程序时,我第一次尝试在处理 class 中访问设置 class 时,我崩溃并显示消息 No ObservableObject of type MeetingStats found。 A View.environmentObject(_:) for MeetingStats may be missing as an ancestor of this view. MeetingStats 的 View.environmentObject(_:) 作为该视图的祖先可能会丢失。

SceneDelegate场景委托

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var meetingStats = MeetingStats()
    var meeting = Meeting()
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
    {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            // passing EnvironmentObjects 
            window.rootViewController = UIHostingController(rootView:
                                                                ContentView()
                                                                .environmentObject(meeting)
                                                                .environmentObject(meetingStats)
                                                             )
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}

Content View is a set of tabs, one for meeting, one for setup and one for statistics内容视图是一组选项卡,一个用于会议,一个用于设置,一个用于统计

meeting.swift - grossly simplified to show the problem area meeting.swift - 严重简化以显示问题区域

//
//  meeting.swift
import Foundation
import SwiftUI
import Combine
import Intents
import os
class Meeting: ObservableObject {
    @EnvironmentObject var meetingStats: MeetingStats
    @objc func calcQuorumEvents() {
   // LOTS of calcualtions     
        self.meetingStats.totalWasteAmount = totalWasteAmount. // HERE's the Crash
        self.meetingStats.totalWasteAmountPersonal = totalWasteAmountPersonal
        self.meetingStats.totalLifetimeWasteAmount = totalLifetimeWasteAmount
    }
  }

Is the issue I am not passing explicitly passing the values to the tabs from the contentView?问题是我没有明确地将值从 contentView 传递给选项卡吗? I have tried explicitly passing the Environment object to the meetingView but still receive the same error:我尝试将 Environment object 显式传递给 meetingView 但仍然收到相同的错误:

iOSMeetingView()
                .environmentObject(meeting)
                .environmentObject(meetingStats)
                .tabItem {
                    Image("presentation")
                    Text("Meeting")
            }.tag(1)

I didn't think that was required as Swift was to look in the object hierarchy to find the object.我不认为这是必需的,因为 Swift 是在 object 层次结构中查找 object。

Did you add the environment objects in view iOSMeetingView?您是否在 iOSMeetingView 视图中添加了环境对象?

@EnvironmentObject var meetingStats: MeetingStats

Edited: I am not sure about your requirement.编辑:我不确定你的要求。 Here is my thought.这是我的想法。 Pass EnvironmentObject meetingStats only to view and you will get the value changes of meetingStats while updating in Meeting.仅通过 EnvironmentObject meetingStats 进行查看,您将在 MeetingStats 更新时获取 meetingStats 的值变化。

class Meeting {
   func calcQuorumEvents(meetingStats: MeetingStats) {
      meetingStats.totalWasteAmount = 12 // HERE's the Crash
      meetingStats.totalWasteAmountPersonal = 60
      meetingStats.totalLifetimeWasteAmount = 8
  }
}

class MeetingStats: ObservableObject  {
    @Published var totalWasteAmount: Int
    @Published var totalWasteAmountPersonal: Int
    @Published var totalLifetimeWasteAmount: Int
    
    init() {
        totalWasteAmount = 0
        totalWasteAmountPersonal = 0
        totalLifetimeWasteAmount = 0
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM