Sorting CoreData entity with a NSComparisonResult

2020-07-18 12:03发布

问题:

I have this distanceSorter.h/distanceSorter.m:

@interface CLLocation (DistanceComparison)

- (NSComparisonResult) compareToLocation:(CLLocation *)other;

@end

@implementation CLLocation (DistanceComparison)
- (NSComparisonResult) compareToLocation:(CLLocation *)other {

CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:[[NSUserDefaults standardUserDefaults] floatForKey:@"lastProcessedLatitude"] longitude:[[NSUserDefaults standardUserDefaults] floatForKey:@"lastProcessedLongitude"]];

CLLocationDistance thisDistance = [self distanceFromLocation:currentLocation];
CLLocationDistance thatDistance = [other distanceFromLocation:currentLocation];
if (thisDistance < thatDistance) { return NSOrderedAscending; }
if (thisDistance > thatDistance) { return NSOrderedDescending; }
return NSOrderedAscending;
}
@end

It works fine with Arrays when i do this:

[someArray sortedArrayUsingSelector:@selector(compareToLocation:)];

but...I want to use it as a sortDescriptor of a NSFetchedResultsController like so:

NSSortDescriptor *sortDistance = [[NSSortDescriptor alloc] 
                                   initWithKey:@"LocationObject" 
                                   ascending:YES 
                                   selector:@selector(compareToLocation:)];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDistance]];

The "LocationObject" in the entity is a "Transformable" and is stored as a CLLocation.

I am getting this on the performFetch:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: compareToLocation:'

THANK YOU IN ADVANCE FOR YOUR HELP :)

回答1:

I assume you're using a SQL store?

If so you're limited in the sort descriptors you can use:

The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work. The supported sort selectors are compare: and caseInsensitiveCompare:, localizedCompare:, localizedCaseInsensitiveCompare:, and localizedStandardCompare: (the latter is Finder-like sorting, and what most people should use most of the time). In addition you cannot sort on transient properties using the SQLite store.

From http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/Articles/cdPersistentStores.html#//apple_ref/doc/uid/TP40002875-SW11

This means you can't do what you're trying to do in a fetch request. The simplest thing to do would be to sort the results after you've received them from the database, assuming that you can fit it all in memory.