Что Apple имеет в виду под @ObjectBinding, которую нужно передать через view? - PullRequest
0 голосов
/ 14 февраля 2020

Я недавно изучал SwiftUI. И поскольку я видел поток данных по видео SwiftUI от Apple , объясняющий разницу между @ObjectBinding и @EnvironmentObject, у меня возник вопрос. Что означает яблоко:

Вы должны передавать модель от прыжка к прыжку в @ObjectBinding? (29 ': 00 ")

Нужно ли передавать объект, используя @binding, в других представлениях для их использования?

Что если мы не используем @binding и ссылаемся на него, используя Другой @ObjectBinding?

Это создает неудобства или заставляет SwiftUI работать неправильно или представления не синхронизируются c друг с другом?

1 Ответ

1 голос
/ 14 февраля 2020

[Edit: обратите внимание, что @ObjectBinding больше не существует; вместо этого вы можете использовать @State, чтобы пометить переменную экземпляра как требующую представление refre sh при его изменении.]

Когда представление объявляет переменную @State или @Binding, ее значение должно быть явно передано от родителя представления. Поэтому, если у вас длинная иерархия представлений, а внизу используется какой-то фрагмент данных сверху, вы должны закодировать каждый уровень этой иерархии, чтобы узнать и передать данные.

В своем комментарии на 29:00, он противопоставляет это использованию @EnvironmentVariable в дочернем представлении, которое ищет во всей иерархии этот фрагмент данных. Это означает, что любые представления, которые явно не нуждаются в данных, могут эффективно игнорировать их. Зарегистрировать переменную нужно только один раз (через .environmentObject(_) в представлении).

Вот надуманный пример. Учитывая некоторый тип данных, соответствующий ObservableObject,

class SampleData: ObservableObject {
    @Published var contents: String

    init(_ contents: String) {
        self.contents = contents
    }
}

Рассмотрим эту иерархию представлений:

struct ContentView: View {
    @State private var data = SampleData("sample content")

    var body: some View {
        VStack {
            StateViewA(data: self.data)

            EnvironmentViewA()
                .environmentObject(self.data)
        }
    }
}

struct StateViewA: View {
    @State var data: SampleData

    var body: some View {
        StateViewB(data: self.data)
    }
}

struct StateViewB: View {
    @State var data: SampleData

    var body: some View {
        Text(self.data.contents)
    }
}

struct EnvironmentViewA: View {
    var body: some View {
        EnvironmentViewB()
    }
}

struct EnvironmentViewB: View {
    @EnvironmentObject var data: SampleData

    var body: some View {
        Text(self.data.contents)
    }
}

Результатом в ContentView будет два представления, отображающие один и тот же фрагмент текста , В первом случае StateViewA должен передавать данные своему дочернему элементу (т. Е. Модель передается из «прыжка в прыжок»), в то время как во втором EnvironmentViewA вообще не нужно знать о данных.

...