问题
I would like to construct a NSPredicate or NSSortDescriptor (Core Data search) that is based on the content of an array.
The array will consists of userId:s
in the right order:
[1, 2, 5, 3];
I would like to present the result for my NSFetchedResultsController in the same order.
So I will:
- Get the right users (I have done this)
- Sort the list of users based on my sorted array with
userId
s.
Is this possible to do, and how can I do it?
回答1:
I think that is not possible. Sorting the results of a fetch request (for a SQLite-based store) is done on the SQLite level, and can use only persistent attributes stored in the database. The sort descriptor cannot use Objective-C functions or variables.
So either
- you add an additional attribute to your entity that describes the intended ordering (if that is possible), or
- you sort the results according to your needs after fetching them (which means that you cannot use a fetched results controller for automatic change tracking anymore). Perhaps you can use the method described here: https://stackoverflow.com/a/15618277/1187415.
回答2:
The above answer is not exactly true. You can do what you want, but it's a bit complicated.
- Create a category on NSNumber (userID is a number, right?)
Put a + global variable of NSArray type onto category using objc_setAssoc....
@interface NSNumber(MyExtension) + (NSArray *) orderingArray; + (void) setOrderingArray: (NSArray *)array; - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber; @end int keyVar = 0; @implementation NSNumber(MyExtension) + (NSArray *) orderingArray { return objc_getAssociatedObject(self, &keyVal); } + (void) setOrderingArray: (NSArray *)array { objc_setAssociatedObject(self, &keyVal, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber; { NSArray *a = [self.class orderingArray]; if(!a) return NSOrderedSame; return [@([a indexOfObject:self]) compare: @([a indexOfObject:theOtherNumber])]; }
Set the array somewhere:
[NSNumber setOrderingArray:myArrayWithKeys];
Use sort descriptor of type:
[NSSortDescriptor sortDescriptorWithKey:@"userId" ascending:YES selector @selector(myOwnCompareMethodUsingArray:)]
This will apparently work as it works for strings with localizedCaseInsensitiveCompare: However, it will degrade performance of the query if it is big enough and override any fetchLimit/fetchOffset optimizations. Remember that the field you are operationg on has to be unique, otherwise it will all go to hell.
来源:https://stackoverflow.com/questions/15729454/sort-nsfetchedresultscontroller-result-based-on-array