- I have an Item
Entity and a Tag
Entity.
- Items can have multiple Tags and Tags can be linked to multiple Items (many to many relationship).
- The relationship is an "Ordered Relationship" (using Ordered relationship in IOS5) both ways.
I want to fetch all child tags for a given item
Im using the following fetch request:
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];
The above sort descriptor returns data (which I assume is in some order) but then crashes:
[_NSFaultingMutableOrderedSet compare:]: unrecognized selector sent to instance 0x10b058f0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[_NSFaultingMutableOrderedSet compare:]: unrecognised selector sent to instance 0x10b058f0'
If I give an empty sort descriptors array then I dont get a crash but the result is not ordered.
How do I correctly implement the sort descriptor in a many to many relationship using the ordered relationship feature in ios5?
I think you may be misapprehending what an ordered relationship means in Core Data. As per this question, "ordered" doesn't mean "with regards to some property" - instead, "ordered" means "preserves the user's order" (or another specific order that would otherwise seem arbitrary). Some examples:
In your case, you try to apply a sort descriptor to the set of ordered sets (the values for the tags
property) that you're fetching. This is the cause of your crash - the NSOrderedSet subclass (_NSFaultingMutableOrderedSet
, in your case) doesn't implement the -compare:
method that the sort descriptor would use to sort them, and so you get that exception.
I think a good solution for you would be to not use a sort descriptor at all; instead, if you want to change the preserved ordering for display to the user, get the NSOrderedSet value for tags
on some Item, then get an array out of it with your own sort using -sortedArrayUsingComparator:
. This will keep the data in the right order in Core Data but let you reorder it yourself programmatically.
At a higher level, you may also want to consider whether or not you really need order in your relationships. It incurs a significant performance penalty, and all you really get back is the original order in which tags were added to items (or vice versa). If you intend to change that order every time you display the tags, then you're taking that performance hit for no real benefit - make your relationships unordered, then either continue sorting programmatically or use a sort descriptor on an aggregate key, such as tags.@count
, as suggested in the comments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With