在 Swift Core Data 中对存储的数据模型提取进行排序

Posted

技术标签:

【中文标题】在 Swift Core Data 中对存储的数据模型提取进行排序【英文标题】:Sorting stored Data Model Fetches in Swift Core Data 【发布时间】:2017-12-06 06:21:13 【问题描述】:

在 Core Data 中,可以使用 Xcode 将查询保存为数据模型中的获取请求。模型中似乎没有任何方法可以为结果设置排序顺序。更糟糕的是,如果您稍后尝试在代码中添加排序:

fetchRequest.sortDescriptors = [ NSSortDescriptor( key: #keyPath(Venue.name), ascending: true) ]

运行时会抛出错误

无法修改不可变模型中的命名提取请求。

这表明由于 fetch 是在模型中定义的,所以现在它是只读的。

这是否实际上意味着如果您需要一个排序的结果集,您就不能将获取请求存储在模型中?

[请注意,我不是在问一般如何对 fetches 进行排序,而是仅在可以将 sorted fetches 存储在模型中或稍后添加排序的情况下]

【问题讨论】:

【参考方案1】:

我刚刚遇到了同样的问题。 答案就在苹果自己的documentation:

但是,一旦使用模型,就不得更改它。这是在运行时强制执行的——当对象管理器第一次使用模型获取数据时,整个模型变得不可编辑。在该点之后对模型或其任何子对象进行变异的任何尝试都会引发异常。如果您需要修改正在使用的模型,请创建一个副本,修改该副本,然后丢弃旧模型中的对象。

要对来自 Xcode 的获取请求进行排序,请使用

func fetchRequestFromTemplate(withName name: String, substitutionVariables variables: [String : Any]) -> NSFetchRequest<NSFetchRequestResult>?

而是,因为它返回一个获取请求模板的副本。

我的这段代码似乎有效(到目前为止):

 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else 
        return
    

    let managedContext = appDelegate.persistentContainer.viewContext
    let mom: NSManagedObjectModel = appDelegate.persistentContainer.managedObjectModel
    let filteredFetchRequest = mom.fetchRequestFromTemplate(withName: "SetsWithNotes", substitutionVariables: ["notes" : (Any).self])
    let sort = NSSortDescriptor(key: #keyPath(MaxRepSet.date), ascending: false)
    filteredFetchRequest!.sortDescriptors = [sort]
    do 
        maxRepSetList = try managedContext.fetch(filteredFetchRequest!) as! [MaxRepSet]
        print(maxRepSetList.count)
     catch let error as NSError 
        print("Could not fetch. \(error), \(error.userInfo)")
    

【讨论】:

这帮助我找到了解决方案。就我而言,我在设置NSPersistentContainer 之前调用fetchRequestTemplate(forName:) 并设置sortDescriptors 属性。值得注意的是,这似乎是“坚持”——我可以在我的应用程序的其他地方(在同一型号上)调用fetchRequestTemplate(forName:),并且排序仍然设置。我认为我不喜欢这种在两个地方配置请求的方法,但很高兴知道它至少是可能的。【参考方案2】:

我建议这样:

1- 将模型存储在核心数据中

2- 获取数据并按您想要排序的属性将它们排序到新数组中

3- 创建新模型并在此模型中保存新的排序数组,现在您可以将其存储在任何地方,

如果您想将其存储在 userDefaults 中,您需要对模型进行编码和解码

4- 删除最旧的模型

祝你好运??

【讨论】:

以上是关于在 Swift Core Data 中对存储的数据模型提取进行排序的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 和 XCode 在 Core Data 中存储整数

Swift:在 Core Data 中存储自定义类的数组

swift 在Core Data中存储Swift值类型

Core Data 使用 Swift 保存数据

Swift - 向 Core Data 添加启用 iCloud 的持久存储

Core Data 数据库正确存储