[Программирование, Разработка под iOS, Swift] Разница между @StateObject, @EnvironmentObject и @ObservedObject в SwiftUI (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Перевод статьи подготовлен в преддверии старта курса "iOS Developer. Professional".
Эту неделю я решил посвятить потокам данных в SwiftUI. В этой статье мы обсудим разницу между обертками свойств (property wrappers) @StateObject, @EnvironmentObject, и @ObservedObject, поскольку я знаю, что это самая запутанная тема для новичков в SwiftUI.Зачем нужны обертки свойств в SwiftUI?SwiftUI использует неизменяемые (immutable) типы структур для описания иерархии представлений. Все представления, которые предоставляет SwiftUI, неизменяемые. Вот почему SwiftUI дает нам набор оберток свойств - для обработки изменений данных. Обертки свойств позволяют нам объявлять себя внутри представлений SwiftUI, но хранить данные вне представления, объявляющего обертку.@StateObject@StateObject - это новая обертка свойства, которая инициализирует экземпляр класса, соответствующего протоколу ObservableObject, и сохраняет его во внутренней памяти фреймворка SwiftUI. SwiftUI создает только один @StateObject для каждого контейнера, который его объявляет, и хранит его вне жизненного цикла представления. Давайте посмотрим на несколько примеров, в которых мы используем @StateObject для сохранения состояния целого приложения.
import SwiftUI
@main
struct CardioBotApp: App {
@StateObject var store = Store(
initialState: AppState(),
reducer: appReducer,
environment: AppEnvironment(service: HealthService())
)
var body: some Scene {
WindowGroup {
RootView().environmentObject(store)
}
}
}
Как видите, @StateObject идеально подходит для хранения состояния целого приложения и передачи его различным сценам или представлениям внутри вашего приложения. SwiftUI сохранит его в специальной памяти фреймворка, чтобы ваши данные находились в безопасном месте вне сцены или жизненного цикла представления. Если хотите узнать больше о реализации концепции Single State Container, читайте мою статью «Redux-подобный контейнер состояний в SwiftUI. Основы».@ObservedObject@ObservedObject это еще один способ подписаться и следить за изменениями в ObservableObject. SwiftUI не контролирует жизненный цикл @ObservedObject - вы должны следить за этим самостоятельно. @ObservedObject идеально подходит для случая, когда у вас есть ObservableObject, хранящийся в @StateObject, и вам нужно поделиться им с каким-либо реюзабельным представлением. Я упомянул реюзабельные представления потому что я сам использую CalendarContainerView в нескольких местах в моем приложении, и я не хочу, чтобы оно зависело от внешних условий. Я использую @ObservedObject, чтобы явно указать данные, используемые представлением в данном конкретном случае.
NavigationLink(
destination: CalendarContainerView(
store: transformedStore,
interval: .twelveMonthsAgo
)
) {
Text("Calendar")
}
Если хотите узнать больше об использовании Container View, читайте мою статью «Redux-подобный контейнер состояний в SwiftUI. Container Views".@EnvironmentObject@EnvironmentObject - отличный способ неявно внедрить экземпляр класса, который соответствует ObservableObject, в часть иерархии представления. Предположим, в вашем приложении есть модуль, который содержит 3-4 экрана, и все они используют одну и ту же ViewModel. Если вы не хотите явно передавать одну и ту же ViewModel из одного представления в другое, тогда вам понадобится @EnvironmentObject. Давайте посмотрим, как мы можем его использовать.
@main
struct CardioBotApp: App {
@StateObject var store = Store(
initialState: AppState(),
reducer: appReducer,
environment: .production
)
var body: some Scene {
WindowGroup {
TabView {
NavigationView {
SummaryContainerView()
.navigationBarTitle("today")
.environmentObject(
store.derived(
deriveState: \.summary,
embedAction: AppAction.summary
)
)
}
NavigationView {
TrendsContainerView()
.navigationBarTitle("trends")
.environmentObject(
store.derived(
deriveState: \.trends,
embedAction: AppAction.trends
)
)
}
}
}
}
}
В приведенном выше примере мы внедряем environmentObject в иерархию представлений SummaryContainerView. SwiftUI неявно предоставит доступ для внедренных environmentObject-ов ко всем дочерним представлениям, которые находятся внутри SummaryContainerView. Мы можем быстро получить и подписаться на внедренные environmentObject-ы, используя обертку свойства @EnvironmentObject.
struct SummaryContainerView: View {
@EnvironmentObject var store: Store<SummaryState, SummaryAction>
var body: some View {
//......
Я должен упомянуть, что @EnvironmentObject имеет тот же жизненный цикл, что и @ObservedObject. Это означает, что вы можете получить новый environmentObject всякий раз, когда создаете его внутри представления, которое может быть воссоздано с помощью SwiftUI.Если хотите узнать больше о продвинутых методах использования Single State Container, читайте мою статью «Redux-подобный контейнер состояний в SwiftUI. Лучшие практики". ЗаключениеСегодня мы поговорили о различиях между обертками свойств @StateObject, @EnvironmentObject, и @ObservedObject. Надеюсь, эта статья поможет вам понять, какая обертка свойства лучше всего подходит для вашего случая. Не стесняйтесь подписываться на меня в Твиттере и задавать свои вопросы, связанные с этой статьей. Спасибо за ваше внимание, до встречи на следующей неделе!
===========
Источник:
habr.com
===========
===========
Автор оригинала: Majid
===========Похожие новости:
- [Python, Программирование, Машинное обучение] Быстрый градиентный бустинг с CatBoost (перевод)
- [Программирование, Управление проектами, Управление продуктом, Карьера в IT-индустрии] Pet-проекты: зачем они нужны, и стоит ли тратить на это время в 2020 году + опрос
- [Информационная безопасность, Программирование, Java, GitHub, Софт] Архитектурные подходы к авторизации в серверных приложениях: Activity-Based Access Control Framework
- [Разработка под iOS, Системы сборки, Облачные сервисы] Интеграция CI/CD для нескольких сред с Jenkins и Fastlane. Часть 2 (перевод)
- [Программирование, Java, Kotlin] Переезд из Java в Kotlin: как забрать коллекции с собой
- [Программирование, Разработка под iOS, Разработка мобильных приложений] SPM: модуляризация проекта для увеличения скорости сборки
- [Open source, PHP, Программирование, Компиляторы] ВКонтакте снова выкладывает KPHP
- [Программирование, C++] Работа с файлами в C++ с использованием Boost
- [Разработка веб-сайтов, JavaScript, Программирование] 20+ ES6-сниппетов для решения практических задач (перевод)
- [Программирование, Java, SQL, Kotlin] Spring: Ускоряем запись в базу данных с помощью XML
Теги для поиска: #_programmirovanie (Программирование), #_razrabotka_pod_ios (Разработка под iOS), #_swift, #_swift, #_ios, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_programmirovanie (
Программирование
), #_razrabotka_pod_ios (
Разработка под iOS
), #_swift
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:21
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Перевод статьи подготовлен в преддверии старта курса "iOS Developer. Professional".
Эту неделю я решил посвятить потокам данных в SwiftUI. В этой статье мы обсудим разницу между обертками свойств (property wrappers) @StateObject, @EnvironmentObject, и @ObservedObject, поскольку я знаю, что это самая запутанная тема для новичков в SwiftUI.Зачем нужны обертки свойств в SwiftUI?SwiftUI использует неизменяемые (immutable) типы структур для описания иерархии представлений. Все представления, которые предоставляет SwiftUI, неизменяемые. Вот почему SwiftUI дает нам набор оберток свойств - для обработки изменений данных. Обертки свойств позволяют нам объявлять себя внутри представлений SwiftUI, но хранить данные вне представления, объявляющего обертку.@StateObject@StateObject - это новая обертка свойства, которая инициализирует экземпляр класса, соответствующего протоколу ObservableObject, и сохраняет его во внутренней памяти фреймворка SwiftUI. SwiftUI создает только один @StateObject для каждого контейнера, который его объявляет, и хранит его вне жизненного цикла представления. Давайте посмотрим на несколько примеров, в которых мы используем @StateObject для сохранения состояния целого приложения. import SwiftUI
@main struct CardioBotApp: App { @StateObject var store = Store( initialState: AppState(), reducer: appReducer, environment: AppEnvironment(service: HealthService()) ) var body: some Scene { WindowGroup { RootView().environmentObject(store) } } } NavigationLink(
destination: CalendarContainerView( store: transformedStore, interval: .twelveMonthsAgo ) ) { Text("Calendar") } @main
struct CardioBotApp: App { @StateObject var store = Store( initialState: AppState(), reducer: appReducer, environment: .production ) var body: some Scene { WindowGroup { TabView { NavigationView { SummaryContainerView() .navigationBarTitle("today") .environmentObject( store.derived( deriveState: \.summary, embedAction: AppAction.summary ) ) } NavigationView { TrendsContainerView() .navigationBarTitle("trends") .environmentObject( store.derived( deriveState: \.trends, embedAction: AppAction.trends ) ) } } } } } struct SummaryContainerView: View {
@EnvironmentObject var store: Store<SummaryState, SummaryAction> var body: some View { //...... =========== Источник: habr.com =========== =========== Автор оригинала: Majid ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_programmirovanie ( Программирование ), #_razrabotka_pod_ios ( Разработка под iOS ), #_swift |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:21
Часовой пояс: UTC + 5