首页 > 解决方案 > ObservableObject 在我的类中有不同的实例化

问题描述

我有一个 ObservableObject 存储用户想要的当前国家信息,我希望在所有视图和类之间共享它。我在场景委托中正确声明了它,所以没有问题。

import Foundation

class GlobalData: ObservableObject {

    @Published var whichCountry: String = "italy"
}

这是我在哪里调用环境对象来获取 whichCountry 的主要观点。当用户单击按钮时,它将打开 ListOfCountriesView() 并通过它传递 EnvironemtnObject 以更新用户想要的新国家/地区。

import SwiftUI

struct InDepthView: View {
    @State var showList = false
    @EnvironmentObject var globalData: GlobalData
    @ObservedObject var data = getDepthData(globalData: GlobalData())

    var body: some View {
        VStack(alignment: .leading) {
        Button(action: { self.showList.toggle() }) {
                VStack(alignment: .leading) {
                    HStack {
                        Text("\(self.data.globalDatam.whichCountry.uppercased())")
                    }
                }
            }
            .sheet(isPresented: $showList) {
                ListOfCountriesView().environmentObject(GlobalData())
            }
        }
    }
}
import SwiftUI

struct ListOfCountriesView: View {

    @EnvironmentObject var globalData: GlobalData

    var body: some View {
        ScrollView {
            VStack(spacing: 15) {
                Text("List of Countries")
                    .padding(.top, 25)

                    Button(action: {
                        self.globalData.whichCountry = "usa"
                        self.presentationMode.wrappedValue.dismiss()
                    }) {
                        VStack {
                            Text("\(self.globalData.whichCountry)")
                                .font(.system(size: 25))
                            Divider()
                        }
                    }
            }
        }
    }
}

struct ListOfCountriesView_Previews: PreviewProvider {
    static var previews: some View {
        ListOfCountriesView().environmentObject(GlobalData())
    }
}

当用户更改国家/地区时,我希望 InDepthView.swift 文件中的此类使用新字符串进行更新。但由于某种原因,根据 ListOfCountriesView() 中发生的情况,当它应该更改为“usa”时,它仍然显示“italy”。所以我知道 GlobalData 有两个实例,但我不知道如何解决这个问题。任何帮助将不胜感激,因为我过去两天一直在尝试解决此问题!

class getDepthData: ObservableObject {

    @Published var data : Specific!
    @Published var countries : HistoricalSpecific!
    var globalDatam: GlobalData

    init(globalData: GlobalData) {
        globalDatam = globalData
        print(globalDatam.whichCountry + " init()")
        updateData()
    }

    func updateData() {

        let url = "https://corona.lmao.ninja/v2/countries/" // specific country    
        let session = URLSession(configuration: .default

        session.dataTask(with: URL(string: url+"\(self.globalDatam.whichCountry)")!) { (data, _, err) in

            if err != nil {
                print((err?.localizedDescription)!)
                return
            }

            let json = try! JSONDecoder().decode(Specific.self, from: data!)

            DispatchQueue.main.async {
                self.data = json
            }

        }.resume()
    }
}

/////// 我把这个添加到你提到的代码中。但收到错误

import SwiftUI

struct InDepthView: View {
    @State var showList = false
    @State var pickerSelectedItem = 1
    @EnvironmentObject var globalData: GlobalData
    @ObservedObject var data: getDepthData

    init() {
        self.data = getDepthData(globalData: self.globalData)
    }

ERRROR : self' 在初始化所有存储属性之前使用

标签: swiftswiftui

解决方案


当您调用时,您正在创建第二个 GlobalData 实例

   @ObservedObject var data = getDepthData(globalData: GlobalData())

编辑:删除了将环境对象作为参数传递的示例。这不起作用,它会崩溃。

您将需要进行一些重构以完全不同地构建您的应用程序,或者您可以删除环境对象,而是在您的第一个视图中初始化 GlobalData(),然后将其作为 @ObservedObject 传递给每个后续视图,而不是而不是通过场景委托作为@EnvironmentObject。

以下是伪代码,但我希望能澄清我的意思:

struct ContentView: View {
    @ObservedObject var globalData = GlobalData()
    var body: some View {
        ...
        NavigationLink("Linky link", destination: SecondView(globalData: globalData, data: getDepthData(globalData: globalData))
    }
    }

struct SecondView: View {
    @ObservedObject var globalData: GlobalData
    @ObservedObject var data: getDepthData
    init(globalData: GlobalData, data: getDepthData) {
        self.globalData = globalData
        self.data = getDepthData
    }
        ...
}

推荐阅读