我有一个Item数据类,每个Item都有一个父项和许多子项,它们是来自父属性的LinkingObjects。
简化版本:

@objcMembers class Item: Object {
    dynamic var title: String = ""
    dynamic var parent: Item?
    let children = LinkingObjects(fromType: Item.self, property: "parent")
}

我需要能够重新排列孩子们的顺序,并坚持这种改变。似乎因为LinkingObjects是一种容器类型,所以这是不可能的?在这种情况下,您建议我如何实现这一点——我是否应该将children更改为普通的List<Item>,并且每次都以两种方式手动更新领域?有更好的解决办法吗?

最佳答案

子项的显示顺序很重要,因为用户将希望根据首先要查看的项选择自己的顺序。
这里重要的一点是你想控制“孩子出现的顺序”。如果你能认识到数据的“模型”和数据的“视图”之间的区别,那么你就可以找到答案。请记住,领域模型表示不在您的控制之下,您不需要它。如何将其存储在领域数据库中不是您的问题。
实际上,当您请求LinkingObjects字段时,它的结果可能是数据库查询的结果,而不是直接从表中提取的结果。因此,字段中对象的顺序可能不一致,或者添加其他链接对象可能会导致额外项出现在结果中的任何位置。
正如你所说,重要的是孩子们出现的顺序。这可以通过查询来控制。LinkingObjects类型允许您直接查询,即您可以调用:

item.children.sorted(byKeyPath: "title")

一个建议是在模型类型中添加一个扩展来为您处理排序,为您需要的每种排序类型提供一个访问器,例如:
extension Item
{
  var childrenSortedByTitle: Results<Item>
  {
    return children.sorted(byKeyPath: "title")
  }
}

或者您可以将其设置为一个带有要在查询中使用的布尔参数的函数。或者您可以添加第二个升序/降序查询。您还可以为要排序的每个其他参数添加额外的查询。或者可以定义排序字段的枚举并将其作为参数传递。无论哪种方法最适合你。但是在类扩展本身(IMHO)中隐藏查询细节是绝对值得的。

10-08 12:14