You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中避免SwiftData @Query计算属性重复计算

解决SwiftUI中分组计算重复执行的问题

针对你遇到的@Query数据变化时分组计算重复执行的问题,有两种靠谱的解决方式,适配不同iOS版本:

方法一:iOS 17+ 用@Memoized宏(最简单)

苹果在iOS17新增了@Memoized宏,专门用来缓存计算属性的结果,只有当它依赖的数据源变化时才会重新计算。直接给你的grouped属性加上这个宏就行:

struct GroupListView: View {
    @Query var persons: [Person]
    
    @Memoized
    var grouped: [[Person]] {
        // 你的耗时分组操作
    }
    
    var body: some View {
        VStack {
            Text("There are \(grouped.count) groups")
            
            List {
                ForEach(grouped, id: \.self) { group in 
                    Text("Number of members: \(group.count)")
                }
            }
        }
    }
}

这样不管grouped在body里被调用多少次,只要persons没变化,就只会用缓存的结果,不会重复执行分组逻辑。

方法二:iOS 17以下 用ViewModel监听数据变化

如果需要兼容iOS17之前的版本,可以用ObservableObject做一个视图模型,在里面监听persons的变化,只在数据更新时重新计算分组:

class GroupListViewModel: ObservableObject {
    @Published var grouped: [[Person]] = []
    
    func updateGrouped(with persons: [Person]) {
        // 你的耗时分组操作,赋值给grouped
        grouped = // 分组逻辑
    }
}

struct GroupListView: View {
    @Query var persons: [Person]
    @StateObject private var viewModel = GroupListViewModel()
    
    var body: some View {
        VStack {
            Text("There are \(viewModel.grouped.count) groups")
            
            List {
                ForEach(viewModel.grouped, id: \.self) { group in
                    Text("Number of members: \(group.count)")
                }
            }
        }
        .onChange(of: persons) { newPersons in
            viewModel.updateGrouped(with: newPersons)
        }
        .onAppear {
            // 首次加载时初始化分组
            viewModel.updateGrouped(with: persons)
        }
    }
}

这个方法里,只有当persons发生变化时,才会调用updateGrouped方法重新计算,视图其他状态变化不会触发重复计算。

另外注意:你的ForEach需要添加id: \.self,因为[Person]数组默认不遵循Identifiable协议,否则会编译报错。

内容的提问来源于stack exchange,提问作者Mink96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:48:11