使用 NSComparisonResult 对 CoreData 实体进行排序
Posted
技术标签:
【中文标题】使用 NSComparisonResult 对 CoreData 实体进行排序【英文标题】:Sorting CoreData entity with a NSComparisonResult 【发布时间】:2011-09-03 15:25:08 【问题描述】:我有这个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
当我这样做时,它适用于数组:
[someArray sortedArrayUsingSelector:@selector(compareToLocation:)];
但是...我想将它用作 NSFetchedResultsController 的 sortDescriptor,如下所示:
NSSortDescriptor *sortDistance = [[NSSortDescriptor alloc]
initWithKey:@"LocationObject"
ascending:YES
selector:@selector(compareToLocation:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDistance]];
实体中的“LocationObject”是“Transformable”,存储为CLLocation。
我在 performFetch 上得到这个:
* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“不支持的 NSSortDescriptor 选择器:compareToLocation:”
提前感谢您的帮助:)
【问题讨论】:
那么 LocationObject 是 CLLocation 还是 Transformable 的实例?您所说的“实体中的“LocationObject”是“可转换的”并且存储为 CLLocation。”到底是什么意思? 在数据模型中,当我填充实体时,该字段被定义为“可转换”(因为我认为这是在实体中存储 CLLocation 的唯一方法),它接受 CLLocation 到它。(这有意义吗?:) 我通常只存储普通的东西,如字符串/数字等,第一次存储 CLLocation) 【参考方案1】:我假设您使用的是 SQL 存储?
如果是这样,您可以使用的排序描述符受到限制:
另一方面,SQL 存储将谓词和排序描述符编译为 SQL,并在数据库本身中评估结果。这主要是为了性能,但这意味着评估发生在非 Cocoa 环境中,因此依赖 Cocoa 的排序描述符(或谓词)无法工作。支持的排序选择器是 compare: 和 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
这意味着您无法在获取请求中执行您尝试执行的操作。最简单的做法是在您从数据库中收到结果后对结果进行排序,假设您可以将其全部放入内存中。
【讨论】:
以上是关于使用 NSComparisonResult 对 CoreData 实体进行排序的主要内容,如果未能解决你的问题,请参考以下文章