目标c-iPhone的排序描述符会改变核心数据的位置



我有一个具有两个属性的CoreData实体。一个称为"position",另一个名为"positionChange"。它们都是整数,其中position属性是当前位置,positionChange是上一个位置和新位置之间的差。这意味着positionChange可以是负数。

现在我想按positionChange排序。但我希望它忽略负面价值观。目前我正在按降序排序,结果是:2,1,0,-1,-2。但我想要的是得到这样的结果:2,-2,1,-1,0。

关于如何使用排序描述符来解决这个问题,有什么想法吗?


编辑

我有两个类,一个叫DataManager,另一个包含我的NSNumber类别(positionChange的类型是NSNumber)。

在DataManager中,我有一个名为"fetchData:"的方法,在这里我用一个排序描述符执行我的提取请求:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

我正在为这个请求做更多的事情,但这对这个问题来说并不有趣。

我的NSNumber类别应该与您发布的类别完全相同:在.h:中

@interface NSNumber (AbsoluteValueSort)
- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber;
@end

在.m:中

@implementation NSNumber (AbsoluteValueSort)
- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber
{
    return [[NSNumber numberWithFloat:fabs([self floatValue])] compare:[NSNumber numberWithFloat:fabs([otherNumber floatValue])]];
}
@end

当我在DataManager对象上调用fetchData时,我会得到以下错误:

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

有什么想法吗?我已将NSNumber类别头文件包含在DataManager类中。

代码因unsupported NSSortDescriptor selector错误而失败的原因是您正在使用SQLite数据存储,并试图使用Cocoa方法作为排序描述符。使用SQLite存储,排序描述符被动态转换为SQL,排序由SQLite完成。这确实有助于提高性能,但也意味着排序是在不存在自定义比较方法的非Cocoa环境中进行的。像这样的排序只适用于常见的已知方法,而不适用于任意的Cocoa代码。

一个简单的修复方法是在不进行排序的情况下进行提取,获取结果数组并进行排序。数组可以使用任何你想要的Cocoa方法进行排序,所以med200的类别在那里应该很有用。

如果数据集不是很大,您也可以从SQLite数据存储更改为二进制存储。

假设您的位置Change是NSNumber:,请尝试此操作

@interface NSNumber (AbsoluteValueSort)
-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber;
@end

然后是:

@implementation NSNumber (AbsoluteValueSort)
-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber
{
    return [[NSNumber numberWithFloat: fabs([self floatValue])] compare:[NSNumber numberWithFloat: fabs([otherNumber floatValue])]];
}
@end

然后这样做:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)];

并使用该描述符进行排序。如果你想让-2总是在2之后,或者5总是在-5之后,你可以修改comparePositionChange:,在一个数字是另一个数字的负数的情况下返回NSOrderedAscending。

最新更新