- 我有一个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];
上面的排序描述符返回数据(我假设它是按某种顺序)但随后崩溃:
[_NSFaultingMutableOrderedSet compare:]: unrecognized selector sent to instance 0x10b058f0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[_NSFaultingMutableOrderedSet compare:]: unrecognised selector sent to instance 0x10b058f0'
如果我给出一个空的排序描述符数组,那么我不会崩溃,但结果没有排序。
如何使用ios5中的有序关系功能在多对多关系中正确实现排序描述符?
答案 0 :(得分:15)
我认为您可能误解了有序关系在Core Data中的含义。根据{{3}},“有序”并不意味着“关于某些财产” - 相反,“有序”意味着“保留用户的订单”(或其他看似随意的特定订单)。一些例子:
在您的情况下,您尝试将排序描述符应用于您正在获取的有序集的集合(tags
属性的值)。这是导致崩溃的原因 - 在您的情况下,NSOrderedSet子类(_NSFaultingMutableOrderedSet
)没有实现排序描述符用于对它们进行排序的-compare:
方法,因此您得到了该异常。
我认为一个很好的解决方案是根本不使用排序描述符;相反,如果要将保留的显示顺序更改为用户,请在某个项目上获取tags
的NSOrderedSet值,然后使用Core Data Release Notes使用您自己的排序从中获取数组。这将使核心数据中的数据保持正确的顺序,但您可以通过编程方式对其进行重新排序。
在更高级别,您可能还想考虑您是否真的需要在您的人际关系中订购。它会导致严重的性能损失,您真正得到的只是将标签添加到项目的原始顺序(反之亦然)。如果您打算在每次显示标记时更改该顺序,那么您将获得该性能命中没有真正的好处 - 使您的关系无序,然后继续以编程方式排序或在聚合键上使用排序描述符,例如{ {1}},如评论中所示。