ios - 使用 NSFetchRequest 和 NSPredicate 时 SwiftUI 列表更新缓慢

标签 ios performance core-data swiftui

当前设置下我的列表过滤速度很慢:

struct TechList: View {

@FetchRequest
var devices: FetchedResults<HearingDevice>


@State private var selectedDevice: String?
@ObservedObject var model = Model()

init(predicate: NSPredicate?) {
    let request: NSFetchRequest<HearingDevice> = HearingDevice.fetchRequest()
    request.sortDescriptors = []
    if let predicate = predicate {
        request.predicate = predicate
    }
    _devices = FetchRequest<HearingDevice>(fetchRequest: request)
}

var body: some View {
    List{
        ForEach(devices, id: \.self) { device in
            VStack(alignment: .center) {
                HStack{
                    Text(device.model ?? "Unknown" + " ")
                        .font(.system(size: 17))
                        .fontWeight(.medium)
                        .foregroundColor(self.selectedDevice == device.model ? Color.white:Color.init(hex: "47535B"))
                        .multilineTextAlignment(.leading)
                        .padding(.leading)
                    Spacer()
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 60)
            .background(self.selectedDevice == device.model ? Color.init(hex: "666699"):Color.init(hex: "F6F6F6"))
            .cornerRadius(7.0)
            .onTapGesture {
                self.model.deviceModel = device.model!
                withAnimation(.spring()){
                    self.selectedDevice = device.model!
                }
            }
        }
    }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        .padding(.top, 170.0)
        .padding(.bottom, 23.0)
        .padding(.horizontal, 10.0)
     }
 }

我正在使用 NSPredicate 来过滤我的获取请求。当用户在字段中输入文本时,列表会更新以反射(reflect)输入文本。然而,过滤列表的速度非常慢,我的数据集中只有不到 300 条记录,那么为什么要花这么长时间来过滤呢?我还将在下面发布我的文本字段代码,看看是否有人可以识别出这种缓慢的过滤可能发生在哪里。我想提一下,我还尝试使用 @Published 变量作为输入谓词来跟踪用户输入何时更改,而不是使用 onEditingChanged,但这并没有提高性能。

TextField("Search for Device by name", text: $searchInput, onEditingChanged: {_ in
        self.predicate = NSPredicate(format: "model contains %@", "\(self.searchInput)")

        print("THE PREDICATE: \(String(describing: self.predicate))")

        if self.searchInput == ""{
            self.predicate = nil
        }

    })

最佳答案

问题不在于您的 NSFetchRequest。该问题与 SwiftUI 有关。

您只需添加:

.id(UUID()) 添加到您的列表。

例如:

List(items, id: \.self) {
    Text("Item \($0)")
}.id(UUID())

请参阅https://www.hackingwithswift.com/articles/210/how-to-fix-slow-list-updates-in-swiftui

这样您就可以了解为什么会发生这种情况

关于ios - 使用 NSFetchRequest 和 NSPredicate 时 SwiftUI 列表更新缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59427063/

相关文章:

r - 多核插入符包的性能极其缓慢

c - 使用 RDTSC 访问内存中的 ARRAY 时在 C 中出现意外输出

ios - 删除 TableView 中的核心数据对象

ios - iOS 中的 CGImage 渲染

android - 在 Fragment 的 onCreate 中调用 Firebase 事件监听器

swift - 如何在 Swift 的 CoreData 实体中的特定索引处添加两个项目

ios - 运行FetchRequest时出错(核心数据,SwiftUI)

ios - 接续不合时宜

iphone - 从 iOS 应用访问 iOS 崩溃报告

iphone - 在后台线程上使用 Azure iOS 工具包 SDK