#swift #dependency-injection #swiftui #observableobject #environmentobject
Вопрос:
У меня возникли проблемы с использованием @EnvironmentObject в классе @ObservableObject. Основываясь на некоторых исследованиях, это невозможно, так как объект EnvironmentObject предназначен только для просмотра.
Я прибегнул к следующему, но значение не обновляется динамически.
Например, он инициализируется значением «A», но когда я изменяю значение в классе, использующем EnvironmentObject, значение, найденное в моем классе ObservableObject, остается «A». Он обновляется во всех других местах, которые используют @EnvironmentObject, только не класс API ObservableObject.
Есть ли способ обновить код в API-классе ObservableObject, когда объект EnvironmentObject обновляет опубликованную переменную?
Класс, которому нужна переменная в нем, которая работает как EnvironmentObject, — это класс API.
class SelectedStation: ObservableObject {
@Published var selectedStation: String = "A"
}
class API: ObservableObject {
var selectedStation: SelectedStation
init(selectedStation: SelectedStation) {
self.selectedStation = selectedStation
print(selectedStation.selectedStation)
}
///some code that will utilize the selectedStation variable
}
Что именно я здесь делаю не так?
Ответ №1:
Вы инициализируете другую версию своего класса. Попробуйте добавить public static let shared = SelectedStation()
вот так:
class SelectedStation: ObservableObject {
@Published var selectedStation: String = "A"
public static let shared = SelectedStation()
}
а затем, когда вам нужно будет его использовать, объявите его как:
var selectedStation = SelectedStation.shared
Кроме того, вы должны переименовать @Published var во что-то другое, кроме selectedStation, иначе вы можете столкнуться с неудачной selectedStation.selectedStation
ссылкой на эту переменную.
Наконец, помните @Environment
, что необходимо инициализировать с SelectedStation.shared
помощью so, чтобы все совместно использовали один экземпляр класса.
Комментарии:
1. Это работает безупречно. Спасибо! И я согласен, мне нужно изменить здесь имя, как выбрано в Station. Выбранная станция далека от идеала. Наконец, есть ли у такого рода шаблонов дизайна название?
2. Это по существу, но не совсем одноэлементный шаблон. У истинного синглтона может быть только один экземпляр, что здесь неверно, но до тех пор, пока вы используете
.shared
его, он является эффективным синглтоном. Это очень полезно для вашего единственного источника истины, когда вам нужно использовать его в не-представлении.3. Понял. Теперь есть ли какая-либо причина хранить это в классе ObservableObject? Поскольку это всего лишь общедоступная переменная, похоже, я могу разместить общедоступную статическую функцию let shared = SelectedStation() в любом месте, где захочу. Или это неверное предположение?
4. Если это не
@Published
так , вы не обновите свое представление, когда оно изменится. Это существует только вObservableObject
классе.