Это очень хорошо объяснено в видео 415. WWDC 2019. Вы просто смотрите на один особый случай широкой языковой функции, а именно оболочек свойств.
Оболочка свойств (такая как @State
) на самом делеспособ ссылки на экземпляр типа (обычно struct или enum) с тем же именем (например, State).Последний предоставляет инструкции для превращения этого свойства экземпляра в вычисляемое свойство, чьи методы получения и установки являются методами получения и установки определенного вычисляемого свойства самого себя (его wrappedValue
).Обычно оно также поддерживает частное хранилище, поддерживающее это вычисленное свойство.
Таким образом, после объявления
@State var showFavoritesOnly = true
... showFavoritesOnly
превращается в вычисляемое свойство с предоставлением его получателя и установщикаГосударственной структурой.Когда вы устанавливаете для showFavoritesOnly
значение true, оно направляется через установщик структуры State и заканчивается хранимым свойством экземпляра State.
Все это подразумевает, что где-то там равно aЭкземпляр состояния, связанный с вашим showFavoritesOnly
.И есть, но это скрыто от глаз.Если вы хотите увидеть этот экземпляр State, его имя будет _showFavoritesOnly
.
Хорошо, но когда вы говорите $showFavoritesOnly
, вы не получаете структуру State;Вы получаете структуру Binding.Зачем?Это связано с тем, что оболочка свойства имеет механизм для указания того, каким должно быть возвращаемое значение из имени $
.В случае State это указывает, что это значение должно быть его собственным binding
свойством, которое является Binding (см. Документы: https://developer.apple.com/documentation/swiftui/state).
По удивительному совпадению, isOn
initializer * Toggle берет a Binding (опять же, смотрите документы, https://developer.apple.com/documentation/swiftui/toggle/3232112-init). Вы не могли бы установить isOn
Toggle на showFavoritesOnly
, даже если бы захотели! Вместо этого вы устанавливаете его на Binding<Bool>
предоставляется экземпляром State, так что Toggle имеет автоматическую двустороннюю связь с объектом State. Платформа SwiftUI обеспечивает собственное правильное использование; Toggle может существовать только относительно некоторой привязки, которая действует какосновной источник правды для его состояния вкл / выкл. И поскольку это связывание, а не просто Bool, связь работает в обоих направлениях: когда пользователь нажимает на переключатель в Toggle, изменение значения перетекает вверх в переменную Stateпутем привязки.