Что делает ключевое слово SwiftUI '@State'?

Учебник SwiftUI использует ключевое слово @State для обозначения изменчивого состояния пользовательского интерфейса:

@State var showFavoritesOnly = false

Он предлагает это резюме:

Состояние - это значение или набор значений, которые могут изменяться с течением времени и влиять на поведение представлений, содержимое или макет. Вы используете свойство с атрибутом @State для добавления состояния в представление.

  • Что именно означает ключевое слово?
  • Как @State переменной @State приводит к @State представления?
  • Как другие переменные неизменяемы в body получателя?

Ответ 1

@State слово @State - это @propertyWrapper, функция, недавно появившаяся в Swift 5.1. Как объяснено в соответствующем предложении, это своего рода оболочка значения, избегающая стандартного кода.


Sidenote: @propertyWrapper ранее назывался @propertyDelegate, но с тех пор ситуация изменилась. Смотрите этот пост для получения дополнительной информации.


Официальная документация @State содержит следующее:

SwiftUI управляет хранением любого свойства, которое вы объявляете государством. Когда значение состояния изменяется, представление делает его недействительным и пересчитывает тело. Используйте государство как единственный источник правды для данного взгляда.

Экземпляр State не является самим значением; это средство чтения и изменения значения. Чтобы получить доступ к состоянию, лежащему в основе значения, используйте его свойство value.

Поэтому, когда вы инициализируете свойство, помеченное как @State, вы на самом деле не создаете свою собственную переменную, а скорее предлагаете SwiftUI создать "что-то" в фоновом режиме, которое сохраняет то, что вы установили, и отслеживает его с этого момента! Ваш @State var действует как делегат для доступа к этой оболочке.

Каждый раз, когда ваша @State переменная записывается, SwiftUI будет знать, как это его мониторинг. Он также будет знать, была ли переменная @State прочитана из body View. Используя эту информацию, он сможет пересчитать любой View, ссылающийся на переменную @State в своем body после изменения этой переменной.

Ответ 2

Это хорошо объяснено на примере из видео WWDC - сессия 204 (начинается в 16:00, цитата начинается в 20:15)

Одним из специальных свойств переменных @State является то, что SwiftUI может наблюдать, когда они читаются и пишутся. Поскольку SwiftUI знает, что zoomed было прочитано в body, он знает, что от него зависит представление представления. Что означает - когда переменная меняет структуру, она снова будет запрашивать body используя новое значение @State.

@State как @State свойств также разработана и обоснована в виде потока данных через Swift UI (5:38) WWDC. Он показал, как он решает проблему, когда нам нужно изменяемое значение в неизменяемом (struct) View.

Ответ 3

Если вы знаете о С# и разработке Windows. @State похож, если не совпадает с x:Bind или Binding. Для коллекции он похож, если не совпадает с ObservableCollection.

Как сказал fredpi, SwiftUI перечисляет обновления для переменных с @State свойства @State.

Ответ 4

Позвольте мне добавить кое-что еще, если вы знаете React Native.

Свойство @State очень похоже на объект this.state в React Native.

Например:

struct Foobar: some View {
    @State var username = ""
}
class Foobar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
    };
  }
}

Когда вы изменяете переменную username, они будут иметь тот же эффект, что и рендеринг текущей страницы.

Ответ 5

Если вы нажмете на @State вы увидите, что у него несколько получателей. Один со Value другой с Binding<Value>. SwiftUI, похоже, в значительной степени зависит от реактивного программирования (и их новой инфраструктуры Combine, и, поскольку мы не можем увидеть полную реализацию этих оболочек, я ожидаю, что значения, хранящиеся через @State свойств @State объектом CurrentValueSubject из Combine. Как следует из названия, это по существу хранит текущее значение, которое затем можно использовать в качестве привязываемого свойства с использованием синтаксиса $.