Iphone CoreData对多个关系进行排序

Iphone CoreData对多个关系进行排序,iphone,cocoa-touch,ios,core-data,nssortdescriptor,Iphone,Cocoa Touch,Ios,Core Data,Nssortdescriptor,我正在编写一个iOS应用程序,它有个人记录存储,需要显示按特定方式排序的列表。这些订单的数量是可变的,它们是动态生成的,但我希望它们存储在数据存储中。SQL实现这一点的方法是让ListPositions表具有列表名、persons表中的id和排序键。然后,为了显示一个特定的列表,我可以选择具有给定名称的所有列表位置,拉入引用的人员,然后按排序键进行排序。尝试在CoreDatat中执行此操作时,我遇到了问题。我正在尝试使用以下模式来实现这一点: Person: Name DOB

我正在编写一个iOS应用程序,它有个人记录存储,需要显示按特定方式排序的列表。这些订单的数量是可变的,它们是动态生成的,但我希望它们存储在数据存储中。SQL实现这一点的方法是让ListPositions表具有列表名、persons表中的id和排序键。然后,为了显示一个特定的列表,我可以选择具有给定名称的所有列表位置,拉入引用的人员,然后按排序键进行排序。尝试在CoreDatat中执行此操作时,我遇到了问题。我正在尝试使用以下模式来实现这一点:

Person:
    Name
    DOB
    etc... 
    positions -->> ListPosition

ListPosition:
    listName
    sortKey
    person --> Person
然后,我可以使用NSPredicate获取给定列表中的所有人员 [NSPredicate predicateWithFormat:@ANY positions.listName,如%@,someList];
这使我能够针对一大组人员动态添加列表。问题是我无法使用ListPosition的sortKey字段对人员进行排序。什么NSSortDescriptor会这样做?如果不可能对一对多关系中的一个元素的属性进行提取排序,那么在coredata中获取多个动态排序的另一种方法是什么?我正在使用NSFetchedResultsController显示列表,因此我自己无法在内存中将列表放在一起。我需要用一个NSFetchRequest来完成这项工作。

你说得对-遵循对多关系返回一个NSSet,它没有固有的排序。要获得排序结果,有两个选项:

假设Person/ListPosition是双向关系,则对ListPosition实体执行新的获取请求。在ListPosition中的person关系上进行谓词匹配,类似于[NSPredicate predicateWithFormat:@person=%@,myPerson]。在获取请求中使用所需的任何排序描述符。 按照关系进行操作,这将为您提供一个NSSet。然后使用NSSet的-sortedarrayingdescriptor:方法将其转换为排序数组。
我认为在这种情况下,最好的方法是取回ListPosition实体。为sortKey添加排序描述符在这种情况下它会起作用,因为获取请求位于ListPosition实体上,并使用SetRelationshipKeyPaths为获取请求上的Person预取和列表名关联的Person

[NSPredicate predicateWithFormat:@"listName like %@", someList];

如果我正确地理解了您的模型,那么每个人对于其参与的每个列表都有一个ListPosition。假设我们有一个按姓名发送的列表,那么X个人有X个列表位置,具有相同的listName和sortKey

我将创建包含sortKey属性的实体列表,然后在排序描述符中使用它

entity List:
    - sortKey : string
    - ascending : bool
创建排序描述符并在提取请求中使用它:

[NSSortDescriptor sortDescriptorWithKey:chosenList.sortKey ascending:chosenList.ascending];
然后,您可以拥有任意数量的列表,并且可以轻松地使用其排序键对所有人进行排序

如果您想在数据库中存储您在ListPosition中没有提到的属性索引或任何类似的位置,您可以创建“联合实体”:

entity PersonInList:
    - index : integer
    - person -> Person
    - list –> List

另一个想法是直接在列表实体中排序Person对象集。

我通常向实体添加索引字段类型NSNumber。在添加项目时,很容易计算索引。刚好

object.index = person.positions.count

所以,实际上你不需要位置字段,而是位置关系。将person实体连接到ListPosition实体就足够了。

获取ListPosition,它将作为NSMutableSet提供。然后对集合进行排序,如下所示:

NSMutableSet *positionsSet = [personEntity mutableSetValueForKey:@"positions"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"yourSortKey" ascending:NO];
NSArray *positionsSortedSet = [positionsSet sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

这将根据您的键为您提供一个已排序的数组。

一些更好的格式将使您的问题更容易阅读。我不清楚。我的问题不是如何在对多关系中对对象进行排序,而是如何为一大组对象提供许多不同的排序顺序。我已经编辑了这个问题。但是,如果您对Person对象进行任何编辑,它将不会触发NSFetchedResultsController进行更新,因为ListPosition没有更改。