使用NSComparisonResult对Core Data实体进行排序

时间:2011-09-03 15:25:09

标签: iphone objective-c core-data

我有这个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

当我这样做时,它适用于Arrays:

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

但是......我想将它用作NSFetchedResultsController的sortDescriptor,如下所示:

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

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

实体中的“LocationObject”是“可转换的”并存储为CLLocation。

我在performFetch:

上得到了这个
  

* 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'不支持的NSSortDescriptor选择器:compareToLocation:'

感谢您提前帮助:)

1 个答案:

答案 0 :(得分:9)

我假设您正在使用SQL商店?

如果是这样,您可以使用排序描述符:

  

另一方面,SQL存储将谓词和排序描述符编译为SQL,并在数据库本身中评估结果。这主要是为了提高性能,但这意味着评估是在非Cocoa环境中进行的,因此依赖Cocoa的排序描述符(或谓词)无法工作。支持的排序选择器是比较: caseInsensitiveCompare: localizedCompare: localizedCaseInsensitiveCompare:,以及 localizedStandardCompare :(后者是类似Finder的排序,大多数人应该在大多数时间使用它)。此外,您无法使用SQLite存储对瞬态属性进行排序。

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

这意味着您无法在抓取请求中执行您尝试执行的操作。最简单的做法是在从数据库接收结果后对结果进行排序,假设您可以将其全部放入内存中。