核心数据:在多对多关系中,我应该使用什么作为具有有序集(ios5)的排序描述符

Ash*_*Ash 10 core-data nspredicate ios

在此输入图像描述- 我有一个Item实体和一个Tag实体. - 项目可以有多个标签,标签可以链接到多个项目(多对多关系). - 这种关系是两种方式的"有序关系"(在IOS5中使用有序关系).

我想获取给定项目的所有子标签

我使用以下获取请求:

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Item"];

// Fetch all items that have a given tag
Tag* myTag = ....;
request.predicate = [NSPredicate predicateWithFormat:@"ANY tag == %@", myTag];

// This is my attempt to get the correct sort ordering (it crashes)
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"tag"
                                                                 ascending:YES];
request.sortDescriptors = @[sortDescriptor];
Run Code Online (Sandbox Code Playgroud)

上面的排序描述符返回数据(我假设是按某种顺序)但随后崩溃:

[_NSFaultingMutableOrderedSet compare:]: unrecognized selector sent to instance 0x10b058f0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 
'-[_NSFaultingMutableOrderedSet compare:]: unrecognised selector sent to instance 0x10b058f0'
Run Code Online (Sandbox Code Playgroud)

如果我给出一个空的排序描述符数组,那么我不会崩溃,但结果没有排序.

如何使用ios5中的有序关系功能在多对多关系中正确实现排序描述符?

Tim*_*Tim 16

我想你可能会误解有序关系在核心数据中意味着什么.根据这个问题,"有序"并不意味着"关于某些财产" - 相反,"有序"意味着"保留用户的订单"(或其他看似随意的特定订单).一些例子:

  • 有序的关系对于配方中的步骤(Apple的核心数据发行说明中的示例)是有益的- 这些步骤不一定按照其任何属性(例如他们的文本)进行排序,并且必须维持"如果Core Data没有进行排序,则索引"或"订购"属性".
  • 有序的关系将不会是很好的名称列表-用户可以选择通过第一个或最后一个名称进行排序,例如,和名称的集合并没有真正的内在的排序内部.唯一重要的是显示顺序 - 数据本身不需要维护该顺序.(Apple的文档中的经验法则是,如果用户可以想象在排序说明符之间进行选择,则不应在Core Data中对该关系进行排序.)

在您的情况下,您尝试将排序描述符应用于您要获取的有序集(tags属性的值).这是导致崩溃的原因 - NSOrderedSet子类(_NSFaultingMutableOrderedSet在您的情况下)没有实现-compare:排序描述符用于对它们进行排序的方法,因此您得到了该异常.

我认为一个很好的解决方案就是不要使用排序描述符; 相反,如果要将显示的保留顺序更改为用户,请获取tags某些项目的NSOrderedSet值,然后使用您自己的排序从中获取数组-sortedArrayUsingComparator:.这将使核心数据中的数据保持正确的顺序,但您可以通过编程方式自行重新排序.

在更高的层次上,您可能还想考虑您是否真的需要在您的人际关系中订购.它会导致严重的性能损失,您真正得到的只是将标签添加到项目的原始顺序(反之亦然).如果您打算在每次显示标记时更改该顺序,那么您将获得该性能命中没有真正的好处 - 使您的关系无序,然后继续以编程方式排序或在聚合键上使用排序描述符,例如tags.@count,正如评论中所建议的那样.