在macOS应用程序上,对于12000个条目的FetchRequest极其慢,但在iOS应用程序上却不慢-尽管代码相同(macOS Big Sur / iOS 14上的SwiftUI)

塞巴斯蒂安

编辑(下面的原始文本可以忽略)

我仅使用手动提取(仅执行一次)进行了一些进一步的测试。看来这仅仅是提取请求(仅适用于12000个实体),这非常慢尽管如此,我想知道为什么我应该只针对macOS而不是iOS出现此问题,因为它具有相同的代码?

=========================================

原始帖子

我正在为macOS Big Sur / iOS 14开发一个简单的SwiftUI应用程序,该应用程序通过CloudKit同步“ Card”实体(没什么花哨的东西;大约20个属性和7个关系)。一切正常,但是,(仅)从解码的JSON文件导入12000个条目之后,macOS应用程序(而非iOS应用程序)变得不可用,即冻结/具有很高的CPU使用率。奇怪的是,如果UI上未显示任何数据,例如使用以下简单视图,也会发生此问题:

主视图和卡列表

struct MainView: View {    
    @ObservedObject var model: MainViewModel
    @Environment(\.colorScheme) var colorScheme
  
    var body: some View {
        CardList(predicate: Card.predicate(searchText: self.model.searchText,
                                                        pinned: self.model.filterPinned,
                                                        priority: self.model.getPrioritiesAsArray(),
                                                        subjects: self.model.selectedSubjects,
                                                        bundles: self.model.selectedBundles),
                              sortDescriptor: EntrySort(sortType: self.model.sortType, sortOrder:self.model.sortOrder).sortDescriptor,
                              model: self.model)
    }
    
}

struct CardList: View {    
    @ObservedObject var model: MainViewModel
    @Environment(\.colorScheme) var colorScheme
    
    @Environment(\.managedObjectContext)
    var context: NSManagedObjectContext
    @FetchRequest(
        entity: Card.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \Card.id, ascending: false)
        ]
    )
    private var result: FetchedResults<Card>
    
    init(predicate: NSPredicate?,
         sortDescriptor: NSSortDescriptor,
         model: MainViewModel) {
        
        let fetchRequest = NSFetchRequest<Card>(entityName: "Card")
        fetchRequest.sortDescriptors = [sortDescriptor]
        
        if let predicate = predicate {
            fetchRequest.predicate = predicate
        }
        _result = FetchRequest(fetchRequest: fetchRequest)
        
        self.model = model
    }
  
    var body: some View {        
        Text("TEST")        
    }

}

“ MainViewModel”外观如下(为便于阅读而缩写):

主视图模型

class MainViewModel: ObservableObject {    
    @Published var searchText: String = ""
    @Published var selectedSubjects: [Subject]?
    @Published var selectedBundles: [Bundle]?
    @Published var selectedTags: [Tag]?
    
    @Published var filterPinned: Bool? = nil
    @Published var filterPriorityVeryHigh: Bool = false
    @Published var filterPriorityHigh: Bool = false
    @Published var filterPriorityNormal: Bool = false
    @Published var filterPriorityLow: Bool = false
    
    func getPrioritiesAsArray() -> [CardPriority] {
        var res: [CardPriority] = []
        if self.filterPriorityLow { res.append(CardPriority.Low)}
        if self.filterPriorityNormal { res.append(CardPriority.Normal)}
        if self.filterPriorityHigh { res.append(CardPriority.High)}
        if self.filterPriorityVeryHigh { res.append(CardPriority.VeryHigh)}
        return res
    }
    @Published var sortType = SortType.dateCreated
    @Published var sortOrder = SortOrder.ascending
}

AppDelegate

import SwiftUI

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    
    var window: NSWindow!
    var coreDataStack = CoreDataStack(modelName: "[Name of Model]")
    var mainViewModel = MainViewModel() 
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {  
        coreDataStack.viewContext.automaticallyMergesChangesFromParent = true
        let mainView = MainView(model: mainViewModel)
            .environment(\.managedObjectContext, coreDataStack.viewContext) 
// ...
}

相同的数据已成功同步到该应用程序的iOS版本,并且可以在此处显示而没有任何性能问题(使用相同的控件,即LazyVStack)。但是,由于持续高的CPU使用率,macOS应用程序变得完全无法使用。另外,我看不到任何会不断更改变量从而触发显示实体不断刷新(即触发新的提取请求)的内容。

有人知道为什么会发生此问题吗?

在此先感谢您的任何建议!

塞巴斯蒂安

※我注意到的一件事是Xcode在控制台上泛滥了警告,“ NSKeyedUnarchiveFromData'不应用于取消存档,并且将在以后的版本中删除”,因为我仍在使用[String] -Transformable-Properties卡实体。稍后我将解决此问题,但是由于此警告似乎一直显示,因此我想知道@FetchRequest是否不断获取/评估所有实体吗?此外,我认为显示的大量警告仅应影响Xcode的CPU使用率?

塞巴斯蒂安

我解决了这个问题;似乎确实是警告“ 'NSKeyedUnarchiveFromData'不应用于取消存档,并会在以后的版本中删除”,这导致CPU使用率激增。将“ NSSecureUnarchiveFromDataTransformer”设置为所有数据库实体的所有[String] -Transformable-Properties之后,该问题消失了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章