@State в SwiftUI стал macro. Синтаксис не изменился, но поведение стало лучше.На WWDC26 компания Apple перевела
@State с property wrapper на macro. Для разработчиков это значит, что код останется таким же, как и раньше, но внутри все работает иначе. Основное изменение касается ленивой инициализации observable-объектов, хранящихся в @State.Что изменилось:
Раньше
@State был property wrapper. Теперь это attached macro. В документации указано:
@attached(accessor, names: named(init), named(get), named(set))
@attached(peer, names: prefixed(`_`), prefixed(__), prefixed(`$`))
macro State()
На практике синтаксис не меняется. Код, который вы писали раньше, продолжает работать. Разница только в том, как SwiftUI управляет хранением состояния.
Изменения на практике:
Самое важное - ленивая инициализация для observable-классов в
@State.Раньше, если вы писали так:
@Observable
class ViewModel {
var index = 0
init() {
print("Init")
}
}
struct MyView: View {
@State private var viewModel = ViewModel()
var body: some View {
Button("Index: \(viewModel.index)") {
viewModel.index += 1
}
}
}
Инициализатор ViewModel мог вызываться каждый раз, когда SwiftUI пересоздавал структуру вью. Даже если сам объект хранился и не терялся, его инициализация все равно выполнялась. Это приводило к лишней работе, особенно если в инициализаторе были тяжелые операции.
Теперь, с macro версией
@State, объект создается один раз - когда SwiftUI создает хранилище состояния для вью. И больше не пересоздается при каждом обновлении родителя.Когда это особенно заметно:
Это изменение особенно полезно, когда вы храните в
@State тяжелые объекты: модели с подписками, кэшами, сетевыми запросами при инициализации. Раньше приходилось использовать обходные пути - например, хранить опциональный объект и создавать его в .task.
// Раньше приходилось делать так, чтобы избежать повторной инициализации
@State private var viewModel: ViewModel?
var body: some View {
MyView(viewModel: viewModel)
.task {
viewModel = ViewModel()
}
}
Теперь это больше не нужно. Можно просто писать:
@State private var viewModel = ViewModel()
И быть уверенным, что объект создастся только один раз.
🔗 Читать подробнее
💡 Вывод:
Apple сделала
@State macro, чтобы улучшить производительность в типичных сценариях. Синтаксис остался прежним, код не требует изменений, но observable-объекты в @State теперь инициализируются один раз. Это избавляет от лишнего кода и делает поведение более предсказуемым.Переход на macro для такого базового механизма - это важный сигнал. Apple уверена в своей macro-системе и готова переносить на нее ключевые API. А для разработчиков это просто означает, что SwiftUI становится чуть более эффективным и предсказуемым.
Подписаться на канал:
➡️ Telegram | Max
Закрытый канал:
🚀 Мобильный трудоголик PRO