CoreData fetch() 返回无序对象
Posted
技术标签:
【中文标题】CoreData fetch() 返回无序对象【英文标题】:CoreData fetch() returns objects unordered 【发布时间】:2018-06-07 19:10:45 【问题描述】:我有一个实体,它有一个名称,出于测试目的,我按照最近添加 (0) 到最旧添加的对象的顺序命名它们。
当我第一次启动应用程序时,它会按顺序加载我的实体(0,1,2...),但是如果我更改任何实体的名称属性,那么顺序就会一团糟。我使用 numberOfRows tableview 函数来测试这个,当重新加载 tableView 时调用它(如果我错了,请纠正我):
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else return 0
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "GraphDataSet")
do
graphSetArray.removeAll()
graphSetArray = try managedContext.fetch(fetchRequest)
catch let error as NSError
print("Could not fetch. \(error), \(error.userInfo)")
for i in 0..<graphSetArray.count
let set = graphSetArray[(graphSetArray.count-1)-i]
print("Name: ", set.value(forKeyPath: "name") as? String)
return graphSetArray.count
据我所知,这会清空包含所有实体的数组(尽管我认为这是没有意义的,因为它被设置在下一行,但我想确定一下),然后获取填充数组的实体。然后我向后循环遍历数组(从最近到旧)并获取该索引的实体并打印其名称属性。
这是我每次启动应用程序时的控制台输出:
Name: Optional("0")
Name: Optional("1")
Name: Optional("2")
Name: Optional("3")
Name: Optional("4")
Name: Optional("5")
Name: Optional("6")
这是在我将实体名称值更改为与原来相同的值之后(只是为了保持它的顺序,但在技术上更改值并重新加载 tableView):
Name: Optional("5")
Name: Optional("4")
Name: Optional("1")
Name: Optional("3")
Name: Optional("0")
Name: Optional("2")
Name: Optional("6")
不知道为什么会发生这种情况,因为我每次都以相同的方式获取数据,并且每次重新启动应用程序时,订单都会恢复正常。我唯一的理论是,当实体属性发生变化时,排序就会混乱,没有模式。所以我想知道这个理论是否正确,如果是,那么有什么办法可以阻止顺序改变?
编辑:我刚刚注意到的一件事是,在它出现故障后,每次当我更改值时,它都会保持这个未排序的顺序
【问题讨论】:
【参考方案1】:顺序不一定保留在 CoreData 中,但您可以将排序描述符添加到您的 fetch 请求中,以便以某种方式对其进行排序。如果您希望它按添加的时间排序,则需要在模型中添加时间戳并按此排序。
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "GraphDataSet")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
...
【讨论】:
好的,但是有什么理由让它按顺序加载一次,然后每次加载相同的未排序顺序。每次重新启动应用程序时,未排序的顺序都是不同的,但在应用程序的执行中是一致的 它可能保存在 ram 中,因此之后不会更改顺序,但我不能肯定地告诉你。我可以告诉你的是,订单不能保证保持不变。 好的,我正在实现一个时间戳,我只是为此使用一个属性?【参考方案2】:您确定使用数组作为后备存储吗?自动生成的版本实际上可以是 Sets 而不是 Arrays。
您的提取请求还可以应用排序描述符,以确保结果(无论它们如何存储)以您指定的方式显示给您。
【讨论】:
我没有看到任何方法来指定它作为一个数组获取,但我相信它是一个集合,无法像我在发布的代码中那样使用下标来索引。我读了一个解决方案,有人建议将索引保存为实体的属性,然后使用排序顺序,这是正确的做法吗?同样使用该方法删除实体的最佳解决方案是什么? 抱歉,出于某种原因,我认为您的 GraphDataSet 是从关系中获取的。听起来您实际上应该使用排序描述符 - 并且不要在表视图委托方法中每次都获取这样的数据。理想情况下,您应该查看 Ray Wenderlich 或 objc.io 的 CoreData 书籍 我要实现排序描述符。除了委托中的每次之外,还有另一种获取方式吗?如果一个值被添加/删除,它不需要检查整个数组吗? 谢谢你的帮助,我去看看书 如果你正在使用 UITableViews,你应该考虑使用 NSFetchedResultsController。正确连接后,您不必担心更新表格视图,因为在您更改数据后它都会为您刷新。以上是关于CoreData fetch() 返回无序对象的主要内容,如果未能解决你的问题,请参考以下文章
核心数据 - 访问从 fetch EXC_BAD_ACCESS 返回的对象