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

SwiftUI List视图复用优化:1000行视图创建问题咨询

SwiftUI List 视图复用优化方案

问题分析

SwiftUI 的 List 本身基于底层 UIKit/AppKit 的复用机制(如 UITableViewCell),只会创建屏幕可见数量的底层视图实例。你观察到的 NameTextView 结构体实例被多次创建,是因为 SwiftUI 的视图是值类型,每次 body 计算时都会生成新的结构体对象——不过这类轻量结构体的创建开销极低。若要减少不必要的结构体重建或确保底层视图复用效率,可通过以下方式优化:

优化方案

1. 让子视图遵循 Equatable 协议

通过让 NameTextView 实现 Equatable,SwiftUI 会自动对比视图实例的属性,仅当属性变化时才重建视图,避免不必要的结构体创建:

struct NameTextView: View, Equatable {
    var name: String
    
    var body: some View {
        Text(name)
    }
}

2. 确保数据源的 id 稳定唯一

List 依赖元素的 id 判断是否复用视图,稳定的 id 能避免误判为新元素。你当前用 UUID().uuidString 生成 id 是可行的,但静态数据源可改用更简洁的稳定标识(如索引):

struct ListElement: Identifiable {
    var id: Int
    var name: String
}

func createList() -> [ListElement] {
    (0..<1000).map { ListElement(id: $0, name: "Name \($0)") }
}

3. 简化视图层级(可选)

若 NameTextView 仅用于包裹 Text,可直接在 List 中使用 Text,减少一层视图结构体的创建:

var body: some View {
    List(items) { element in
        Text(element.name)
    }
    .listStyle(PlainListStyle())
}

最终优化代码示例

import SwiftUI

struct ListContentView: View {
    var items = createList()
    
    var body: some View {
        List(items) { element in
            NameTextView(name: element.name)
        }
        .listStyle(PlainListStyle())
    }
}

struct NameTextView: View, Equatable {
    var name: String
    
    var body: some View {
        Text(name)
    }
}

struct ListElement: Identifiable {
    var id: Int
    var name: String
}

func createList() -> [ListElement] {
    (0..<1000).map { ListElement(id: $0, name: "Name \($0)") }
}

#Preview {
    ListContentView()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:56:28