Sort NSFetchedResultsController result based on array?

守給你的承諾、 提交于 2019-12-20 01:55:08

问题


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:

  1. Get the right users (I have done this)
  2. Sort the list of users based on my sorted array with userIds.

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.

  1. Create a category on NSNumber (userID is a number, right?)
  2. 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])];
    } 
    
  3. Set the array somewhere:

    [NSNumber setOrderingArray:myArrayWithKeys]; 
    
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!