使用多个谓词获取请求?

时间:2012-04-10 15:19:38

标签: iphone objective-c ios core-data

我有一个实体Tags,我想执行抓取以获取所有Tags并将其分配给NSFetchedResultsController。但是,我希望获取结果中的第一个对象是TagtagName属性等于"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]];

2 个答案:

答案 0 :(得分: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告诉你可以使用比较器一样,我没有看到他已经回答了你的问题。

你也可以使用一个选择器,只需要在你的模型中实现一个方法来进行比较,我犯了一个错误并且相信你正在做的事情,来自apple doc:

  

选择

     

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

答案 1 :(得分:1)

您可以使用自定义比较方法对NSSortDescriptor本身执行此操作。但是,您还可以在获取它们之后对获取请求的结果进行排序。 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];
}];