@State в iOS 27: Observable-объекты перестали создаваться впустуюСтрока
@State private var model = DataModel() выглядит безобидно, пока в инициализаторе не появится точка останова. SwiftUI пересоздаёт структуру вью на каждом обновлении родителя, и конструктор вызывается снова и снова. Лишние экземпляры система выбрасывает сразу, оставляя первый, а вот код внутри init успевает отработать целиком. Если там разбор конфигурации, поднятие клиента или чтение с диска, за одну прокрутку списка эта работа уходит в мусор десятки раз.
Обходили по-разному. Кто-то возвращался к
@StateObject, ленивому с самого начала, кто-то держал инициализатор пустым и догружал данные в task. Третий путь — вынести объект уровнем выше и прокинуть через окружение.
В SDK
iOS 27, вышедшего 14 сентября 2026,
@State стал макросом, и классы внутри него инициализируются лениво,
ровно один раз за время жизни вью:
@Observablefinal class DataModel {
var items: [Item] = []
init() {
// теперь выполнится один раз, а не на каждом обновлении родителя
}
}
struct FeedView: View {
@State private var model = DataModel()
var body: some View {
List(model.items) { ItemRow(item: $0) }
}
}
Код выглядит так же, как год назад, а поведение под ним другое. Объект перестал быть расходником, поэтому тяжёлую подготовку можно держать прямо в инициализаторе, не растаскивая её по onAppear и task.
Разница заметна там, где вью обновляется часто: на экране с таймером, в ленте с подгрузкой, в любой вложенной иерархии, где родитель перерисовывается из-за чужого состояния. Раньше каждое такое обновление тянуло за собой конструктор модели ребёнка, теперь нет.
Одно осталось прежним. Ленивость распространяется только на выражение в объявлении, так что, если модель присваивается свойству в init() самого вью, инициализатор по-прежнему выполняется на каждом пересоздании, а присвоение игнорируется, и в свойстве может остаться устаревшее значение.
Перепроверить стоит и участки кода,, где инициализатор модели делал что-то неидемпотентное: писал аналитику, инкрементировал счётчик, регистрировался в синглтоне. Такой код годами работал вместе с лишними вызовами, и после перехода на новый SDK число событий изменится.
Заодно в этом же релизе ViewBuilder стал доступен как ContentBuilder, и сборка сложных вложенных вью в Xcode 27 заметно ускорилась. На скорость самого приложения это не влияет, зато сокращает время компиляции.
Если проект уже собирается новым SDK, включать ленивость отдельно не нужно, она работает сама. А вот привычку выносить дорогую инициализацию в task можно пересмотреть: модель снова имеет право быть тяжёлой.
А вы уже поднимали target на iOS 27?
#mobilevkhub #ios