Это Лекция 12 курса Stanford CS193p, весна 2021 года.
На этой фантастической и очень важной Лекции (она длится почти 2 часа) Пол Хэгерти рассматривает супер важную тему — Property Wrappers (“Обертки Свойства”). Мы наконец-то поймем, что такие вещи как @State, @StateObject, @Published, @ObservedObject и другие @штуковины делают под «капотом». Поэтому сначала эту тему профессор представляет теоретически, то есть на слайдах, а затем следует громадная демонстрация, на которой показывается все это в действии, но не только это, а также много всего другого, что можно изучить только в демонстрационном пример: текстовые поля TextField, «всплывающие окна» popover и sheet, навигацию с помощью NavigationView, формы Form, списки List, режим редактирования EditMode и т.д, интересные модификаторы .onDelete, .onMove, .onChange.
Property Wrapper (“Обертка Свойства”) — это просто структура struct, в которую встроен некоторый шаблон “поведения”переменной var, которую эта структура struct “оборачивает”.
Например, @State заставляет переменную var “жить” в “куче” (heap), делая её writable в View, то есть дает возможность “писать” в нее новые значения в противоположность обычным переменным var в View, которые являются unwritable (только для чтения).
Мы знаем, что @Published публикует изменения переменной var, которые заставляют Views перерисовывать себя или делать другие подобные вещи.
То же самое происходит с @ObservedObject переменной var, которая отслеживает изменения в вашей ViewModel и заставляет View перерисовывать себя.
Property Wrapper (“Обертка Свойства”) — это конструкция языка Swift, которая добавляет “синтаксического сахара”, который облегчает выполнение некоторых операций, действительно необходимых для функционирования SwiftUI.
В теоретической части Лекции 12 профессор “вскрывает” эти Property Wrappers (“Обертки Свойства”) и анализирует, что у них находится внутри.
Внутри такой Property Wrapper структуры struct находится очень важная переменная var, которая называется wrappedValue. ТИП переменной var wrappedValue для большинства Property Wrappers (“Оберток Свойства”) совпадает с ТИПом переменной var, которую они оборачивают. Есть еще одна переменная var в этой структуре struct, которая называется projectedValue. Доступ к переменной projectedValue осуществляется с помощью ещё одного “синтаксического сахара” — знака $, например, $emojiArt. У каждого Property Wrapper (“Обертки Свойства”) имеется свой отличающийся от других ТИП projectedValue, это полностью его решение. Например, @Published выбрала для себя в качестве projectedValue “издателя” Publisher, который публикует wrappedValue и никогда Never не ошибается.
Но главный и самый интересный смысл Property Wrapper заключается в том, что структура struct Property Wrapper (“Обертки Свойства”) может делать дополнительные действия при получении (get) или установки (set) своего wrappedValue.
Например, что делает @Published, когда его wrappedValue установлен? Он публикует это значение через свою переменную $emojiArt, которая является “издателем” Publisher. Но не только это, @Published посылает сообщение objectWillChange.send() в ObservableObject, в котором он находится.
Затем профессор подробно рассматривает каждую из известных нам Property Wrappers (“Оберток Свойства”) :
- @State,
- @StateObject,
- @Published,
- @ObservedObject,
- @Binding,
- @EnvironmentObject,
- @Environment.
… и исследует их с 3-х позиций:
- что является wrappedValue
- что она делает с этим wrappedValue
- что собой представляет projectedValue (то есть $ версия)
Далее выполняется демонстрация, в которой мы узнали:
- как передать View нашу ViewModel, используя .environmentObject механизм. Мы внедрили таким образом ViewModel на самый верхний уровень, a затем без всяких усилий с нашей стороны позволили ViewModel “просачиваться” по всем уровням иерархии Views, вплоть до самых нижних уровней с помощью @EnvironmentObject,
- что должны помечать наши “источники истины” (sources of truth) на самом верхнем уровне с помощью @StateObject, чтобы мы всегда могли найти свои “источники истины”, выполнив поиск по @State.
- об этой маленькой хитрости с использованием модификатора .id (), чтобы сделать View одновременно и Identifiable, и уникальным, чтобы заставить его уйти с экрана при изменении .id () и тем самым выполнить “переход” transition и связанную с ним анимацию,
- как создавать контекстные меню contextMenu и как прикреплять их к кнопке Button или вызывать их другого контекстного меню,
- самое главное в SwiftUI, то есть как действует “привязка” @Binding. Научились использовать “привязку” Binding
- для “привязки” к тексту внутри текстового поля TextField,
- для решения о том, когда выводить на экран всплывающие окна” sheet и popover, если меняется нечто, “привязанное” к Bool или Optional значению,
- для обратной “привязки” информацию из наших Views к нашей модели Model,
- о некоторых очень мощных View, таких, как
- форма Form, которая очень проста в использовании и которая организует информацию в очень привлекательном виде,
- список List, который создает красивые списки с отчетливо выделенными строками, но также поддерживает такие модификаторы, как .onDelete и .onMove для ForEach, расположенного внутри него,
- о NavigationView и NavigationLink, a также о возможность установить заголовок с помощью модификатора .navigationTitle и режим отображения этого заголовка с помощью модификатора .navigationBarTitleDisplayMode,
- как разместить специальную кнопку EditButton на панели инструментов toolbar, которая изменяет режим редактирования EditMode в своей окружающей среде @Environment,
- как просто было добавить возможность удаления и перемещения элементов списка List, с помощью модификаторов .onDelete и .onMove для ForEach, расположенного внутри списка List,
- как эффективно использовать фантастический модификатор .onChange,
- как разместить на экране оповещение Alert.
Код демонстрационного примера для Лекции 12 находится на Github для iOS 14 в папке EmojiArtL12.
Русскоязычный неавторизованный конспект Лекции 12, иллюстрированный, хронометрированный и представленный в виде PDF-файла, который можно скачать и использовать offline, а также в формате Google Doc доступны на платной основе.