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