尝试访问由另一个scenedelegate函数在场景委托内部创建的环境对象

问题描述

我已经在scendelegate中创建了一个环境对象,并且还想在我的scenedelegate内的另一个函数中使用它。代码如下:

SceneDelegate.swift

    class SceneDelegate: UIResponder,UIWindowSceneDelegate {
    
        var window: UIWindow?
        //@EnvironmentObject var data: DataFetcher
        var data = DataFetcher()
    
        func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
 
            if let windowScene = scene as? UIWindowScene {
                
                let window = UIWindow(windowScene: windowScene)
                let data = (UIApplication.shared.delegate as! AppDelegate).self.data
                window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
                self.window = window
                window.makeKeyAndVisible()
            }
        }
        
        func handleIncomingDynamicLink(_ dynamicLink: DynamicLink){
            guard let url = dynamicLink.url else {
                print("That's weird. My dynamic link object has no url")
                return
            }
            print("Your incoming link parameter is \(url.absoluteString)")
            guard let components = URLComponents(url: url,resolvingAgainstBaseURL: false),let queryItems = components.queryItems else {return}
            self.data.linkRecieved = true
            print(data.linkRecieved)
        }
func scene(_ scene: UIScene,continue userActivity: NSUserActivity) {
        if let incomingURL = userActivity.webpageURL {
            print("Incoming URL is \(incomingURL)")
            _ = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { (dynamicLink,error) in
                guard error == nil else{
                    print("Found an error! \(error!.localizedDescription)")
                    return
                }
                if let dynamicLink = dynamicLink {
                    self.handleIncomingDynamicLink(dynamicLink)
                }
            }
        }
    }
        

问题在于,当执行handleIncomingDynamicLink函数时,环境对象的linkRecieved变量不会在contentview中更改(我已经验证了该变量在运行后确实变为true)。感谢您对解决此问题的任何见解!

解决方法

您已经为DataFetcher属性分配了一个data实例,大概是为了设置其类型并消除未初始化您的属性的错误。

然后在willConnectTo中,您从DataFetcher数据AppDelegate. Your 数据property and the local willConnectTo variable in DataFetcher`中获得了(That you subsequently add to the environment) now reference different instances of实例,但是您没有没意识到。

基于这个原因,我不太喜欢为属性分配“丢弃”实例。

更好的方法是使用一个隐式展开的可选。这样,如果不为属性分配值,则会崩溃,并迅速找出不正确的地方。

然后在willConectTo中,您可以将AppDelegate中的实例分配给属性,并将其放入环境中。

class SceneDelegate: UIResponder,UIWindowSceneDelegate {
    
        var window: UIWindow?
        //@EnvironmentObject var data: DataFetcher
        var data: DataFetcher!
    
        func scene(_ scene: UIScene,willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) {
 
            if let windowScene = scene as? UIWindowScene {
                
                let window = UIWindow(windowScene: windowScene)
                self.data = (UIApplication.shared.delegate as! AppDelegate).self.data
                window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(data))
                self.window = window
                window.makeKeyAndVisible()
            }
        }
,

您需要注入作为属性的var data,因此删除以下行

let window = UIWindow(windowScene: windowScene)
//let data = (UIApplication.shared.delegate as! AppDelegate).self.data // << this one
window.rootViewController = UIHostingController(rootView: 
   ContentView().environmentObject(self.data))   // << inject own property

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...