С помощью макроса @Query SwiftData я получаю массив элементов модели. Затем я использую вычисляемое свойство для группировки элементов. На мой взгляд, вычисляемое свойство используется дважды и, следовательно, также вычисляется дважды. Если массив длинный и операция сложная, вычисление вычисляемого свойства занимает много времени. Как я могу изменить свой код, чтобы свойство вычислялось только один раз, а затем при каждом изменении данных из @Query?
struct GroupListView: View {
@Query var persons: [Person]
var grouped: [[Person]] {
// expensive operation
}
var body: some View {
VStack {
Text("There are \(grouped.count) groups")
List {
ForEach(grouped) { group in
Text("Number of members: \(group.count)")
}
}
}
}
}
Я попытался сохранить grouped как локальную переменную в GroupListView вместо использования вычисляемого свойства. Проблема этого подхода в том, что мне нужно объявить переменную в инициализаторе, а представление не обновляется при изменении persons.
Я также пытался сохранить grouped как локальную переменную в body, но это приводит к повторному вычислению всякий раз, когда изменяется какое-либо состояние внутри представления, а не только при изменении persons.
Другими словами, вам следует выполнить эту операцию группировки как можно выше по иерархии представлений (представления, расположенные выше по иерархии представлений, как правило, обновляются реже), а затем передать ее подпредставлениям через их инициализаторы.
Сгруппируйте состояние и используйте задачу (id:), чтобы заполнить его, когда оно появляется и изменяется.
вероятно, лучше всего вернуться к @SectionedFetchRequest CoreData, пока @GroupedQuery еще нет. Другой способ — изменить дизайн вашей модели, чтобы вам не нужно было группировать ее при запросе.





Решить это можно, создав Государство для группировки и выполнив задачу по обновлению персон. Код будет выглядеть примерно так: -
@Query var persons: [Person]
@State var grouped: [[Person]]
var body: some View {
// Your current logic
}.task(persons: persons) {
// Grouping logic
}
}
}
Не забудьте изменить переменную зависимости задачи для достижения наилучших результатов.
Вам следует создать
groupedлокальную переменную вbody. Если в представлении есть другие состояния, вам следует устранить их, разбив представления на более мелкие представления. По сути, это то, что вы сделали в опубликованном вами примере кода. ВGroupListViewнет никаких состояний, кроме запроса. Сделайте это и в своем реальном коде.