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

SwiftData @Query导致UI卡顿问题排查与解决方案咨询

问题分析与解决方案

你的@Query基础用法是正确的,UI卡顿并非来自@Query本身,而是由其他细节问题导致的,以下是具体分析和修复方案:

1. 移除@Model类的手动Hashable实现

SwiftData的@Model类默认已经通过内部机制管理对象的唯一性,且自带Identifiable协议支持(基于你定义的id属性)。手动实现Hashable会干扰SwiftData的状态管理,可能触发不必要的视图刷新。

修复方案:删除PlaylistGroup和PlaylistItem中的Hashable相关代码,包括static func ==和hash(into:)方法。

2. 优化LazyVGrid的列定义

当前columns是计算属性,每次视图刷新都会重新创建数组实例,可能导致LazyVGrid频繁触发布局计算。

修复方案:将columns改为静态常量:

// 替换原计算属性
let columns: [GridItem] = [
    GridItem(.flexible(), spacing: 10),
    GridItem(.flexible(), spacing: 10),
    GridItem(.flexible(), spacing: 10)
]

(alignment: .center是默认值,无需显式声明)

3. 简化PlaylistItemView的视图逻辑

原视图中重复的Image创建逻辑会增加渲染开销,且条件分支可能导致视图树频繁重建。

修复方案:通过提取计算属性统一管理图标名称,简化视图代码:

struct PlaylistItemView: View {
    let mode: stateMode

    private var iconName: String {
        switch mode {
        case .normalMode: return "tv"
        case .deleteMode: return "trash.circle.fill"
        case .updateMode: return "arrow.clockwise.circle.fill"
        }
    }

    var body: some View {
        VStack {
            Image(systemName: iconName)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 50, height: 50)
                .padding()

            Text("TEST")
                .foregroundColor(.white)
        }
        .background(Color.black.opacity(0.2))
        .cornerRadius(10)
    }
}

4. 限制@Query的数据加载范围

虽然你当前没有使用PlayListModel的关联数据(groups),但@Query默认会加载完整对象,包括关联关系的引用,可能导致不必要的性能开销。

修复方案:使用projection参数只获取所需属性:

// 仅获取id字段(视图中未用到其他属性)
@Query(projection: \PlayListModel.id) var playList: [PlayListModel] = []

5. 检查动画触发的额外刷新

切换mode时的withAnimation会触发视图过渡,但如果存在其他不必要的视图刷新源(比如之前的计算属性columns),会放大卡顿现象。确保所有视图依赖都是稳定的常量或@State/@Binding等受控状态。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:58:11