0

我有一个实体Tags,我想执行一次提取以获取所有Tags内容并将其分配给NSFetchedResultsController. 但是,我希望获取结果中的第一个对象是TagwithtagName属性等于"All",然后其余的按字母顺序排序。目前我正在这样做,它只是按字母顺序返回所有标签,但我希望命名的标签"All"总是第一个,然后按字母顺序排列。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext];

[fetchRequest setEntity:entity];
NSSortDescriptor *lastDescriptor =
[[[NSSortDescriptor alloc] initWithKey:@"tagName"ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];      

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]];
4

2 回答 2

2

您需要使用您创建的比较器,而不是一个默认值,因此您可以执行以下操作:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext];

[fetchRequest setEntity:entity];
NSSortDescriptor *lastDescriptor =
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:YES comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) {

    if ([tag1 isEqualToString:@"All"]) return NSOrderedAscending;
    if ([tag2 isEqualToString:@"All"]) return NSOrderedDescending;

    return [tag1 compare:tag2];
}] autorelease];      

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

编辑

就像@Andrew Madsen 告诉您可以使用比较器一样,我没有看到他已经回答了您的问题。

您也可以使用选择器,只需要在您的模型中实现一个方法来进行比较,我犯了一个错误并相信这就是您正在做的,来自苹果文档:

选择器

比较对象属性时使用的方法,例如 caseInsensitiveCompare: 或 localizedCompare:。选择器必须指定由 keyPath 标识的属性值实现的方法。用于比较的选择器传递了一个参数,即要与自身进行比较的对象,并且必须返回适当的 NSComparisonResult 常量。选择器必须具有与以下相同的方法签名: - (NSComparisonResult)localizedCompare:(NSString *)aString

于 2012-04-10T15:37:02.780 回答
1

您可以使用自定义比较方法对 NSSortDescriptor 本身执行此操作。但是,您也可以在取回 fetch 请求的结果后对其进行排序。NSArray 有一个名为的方法-sortedArrayUsingComparator:,允许您使用块对数组进行排序,从而使像这样的自定义排序行为非常容易。请参阅下面的示例:

NSArray *sortedResults = [results sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSString *tag1 = [obj1 tagName];
    NSString *tag2 = [obj2 tagName];

    BOOL tag1IsAll = [tag1 isEqualToString:@"All"];
    BOOL tag2IsAll = [tag2 isEqualToString:@"All"];
    if (tag1IsAll && !tag2IsAll) return NSOrderedAscending;
    if (tag2IsAll && !tag1IsAll) return NSOrderedDescending;

    return [tag1 compare:tag2];
}];
于 2012-04-10T15:27:17.080 回答