使用 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 实体进行排序的主要内容,如果未能解决你的问题,请参考以下文章

iOS-数组排序

对 NSIndexPaths 数组进行排序

OC之打乱对象数组

如果我使用比较对对象进行排序,如果其中一个对象为零,我如何告诉它不排序?

排序总结

按降序排序数组(NSArray)