Должен ли я проверить, что я присваиваю другое значение свойству @Published?

#ios #swift #swiftui

Вопрос:

У меня есть простой пример кода, в котором я обновляю @State и @Published свойство с тем же значением (при нажатии кнопки). Теперь я вижу, что затем я присваиваю то же значение @State нет основного вызова view. Но затем я присваиваю @Published свойство, после чего вызывается каждое назначение. Я знаю, что это может быть быстро, но все же могут быть ненужные вызовы тела представления.

Итак, я должен проверить, действительно ли я изменяю значение @Published свойства или есть какие-то другие способы?

 class Object: ObservableObject {
    @Published var state: Bool = false
    
    func setState() {
        state = false
    }
}

struct ContentView: View {
    @State var state: Bool = false
    @ObservedObject var obj = Object()

    var body: some View {
        print(Self._printChanges())
        return VStack {
            Text("(String(state))")
            Button("Tap") {
                self.state = false
                obj.setState()
            }
        }
    }
}
 

Вывод при щелчке по нажатию (3 раза):

 ContentView: _obj changed.
()
ContentView: _obj changed.
()
ContentView: _obj changed.
()
 

Комментарии:

1. Для меня это звучит как преждевременная оптимизация…

2. Я не знаю. У меня есть часть в моем коде. Я проверяю некоторое условие, которое обычно false и очень редко true . Теперь у меня есть обновления для каждого false набора. Вызов большого тела представления кажется пустой тратой ресурсов. С другой стороны, я могу сделать очень простую проверку. И кажется странным, что это работает нормально @State , но не для @Published

3. Ну, вы можете использовать инструменты для измерения производительности вашего приложения с проверкой и без проверки. И нет, это не странно. Именно так State и Published ведут себя.

4. @State является внутренним для представления, но @ObservedObject является внешним ресурсом, поэтому они обрабатываются по-разному и почему представление может отслеживать любые изменения @State свойства.

Ответ №1:

SwiftUI является декларативным, поэтому можно утверждать, что это конкретное поведение является деталью реализации, и я бы не стал беспокоиться об этом. То, что вызывается body SwiftUI, не обязательно означает, что ваш пользовательский интерфейс перерисовывается. Действительно, если каждое представление имеет одинаковую «идентификацию» с неизменными данными, вам не нужно беспокоиться о дополнительных вызовах SwiftUI draw . Система будет знать, что ничего не изменилось, и не понесет накладных расходов пользовательского интерфейса.

Вам не нужно работать над исправлением этого, если вы специально не определили это как узкое место в производительности вашего приложения. Не оптимизируйте ничего, если у вас нет на то веских оснований, иначе вы просто теряете время (так как могут быть другие узкие места, над которыми нужно поработать в первую очередь).