Using KVC in NSSortDescriptor

2019-08-30 08:40发布

问题:

I need to sort a bunch of objects based on an integer that is stored in an NSString.

I know this is one solution and it works:

NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"from" ascending: YES comparator:^(id obj1, id obj2)
{
   if ([obj1 integerValue] > [obj2 integerValue])
   {
       return (NSComparisonResult) NSOrderedDescending;
   }

   if ([obj1 integerValue] < [obj2 integerValue])
   {
       return (NSComparisonResult) NSOrderedAscending;
   }

   return (NSComparisonResult) NSOrderedSame;
}];

self.myObjects = [[self.data allObjects] sortedArrayUsingDescriptors: @[mySortDescriptor]];

My question is, why can't I use KVO for this, it looks much cleaner, eg like this:

NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey: @"from.integerValue" ascending: YES];

And then pass that to my NSFetchRequest

With this code, 200 appears before 21.

回答1:

A sort descriptor for a (SQLite based) Core Data fetch request can only use persistent attributes and a limited set of built-in selectors, but not Objective-C methods like integerValue.

In this case, it seems that the integerValue is just ignored, so that the from values are sorted as strings, and not as numbers.

If you cannot change the attribute type to "Integer" (which would solve the problem as well) then you can use a special selector as a workaround:

NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"from"
                                  ascending:YES
                                   selector:@selector(localizedStandardCompare:)];

localizedStandardCompare is the "Finder-like sort" and sorts strings containing digits according to their numerical value.