使用NSComparisonResult对CoreData实体排序 [英] Sorting CoreData entity with a NSComparisonResult

查看:133
本文介绍了使用NSComparisonResult对CoreData实体排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个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
升序:YES
selector:@selector(compareToLocation :)];

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

实体中的LocationObject是一个Transformable,并存储为CLLocation。 p>

我在performFetch上得到这个:


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


谢谢您HELP:)

解决方案

我假设您使用的是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



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


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 :)

解决方案

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.

这篇关于使用NSComparisonResult对CoreData实体排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆