Как избежать повторных вычислений вычисляемых свойств с помощью @Query SwiftData в SwiftUI

С помощью макроса @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.

Вам следует создать grouped локальную переменную в body. Если в представлении есть другие состояния, вам следует устранить их, разбив представления на более мелкие представления. По сути, это то, что вы сделали в опубликованном вами примере кода. В GroupListView нет никаких состояний, кроме запроса. Сделайте это и в своем реальном коде.

Sweeper 02.09.2024 11:31

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

Sweeper 02.09.2024 11:32

Сгруппируйте состояние и используйте задачу (id:), чтобы заполнить его, когда оно появляется и изменяется.

lorem ipsum 02.09.2024 12:49

вероятно, лучше всего вернуться к @SectionedFetchRequest CoreData, пока @GroupedQuery еще нет. Другой способ — изменить дизайн вашей модели, чтобы вам не нужно было группировать ее при запросе.

malhal 02.09.2024 15:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решить это можно, создав Государство для группировки и выполнив задачу по обновлению персон. Код будет выглядеть примерно так: -

    @Query var persons: [Person]
    @State var grouped: [[Person]]
    
    var body: some View {
        // Your current logic
        }.task(persons: persons) {
           // Grouping logic
        }
    }
}

Не забудьте изменить переменную зависимости задачи для достижения наилучших результатов.

Другие вопросы по теме