具有任意排序的 NSSortDescriptor
Posted
技术标签:
【中文标题】具有任意排序的 NSSortDescriptor【英文标题】:NSSortDescriptor with arbitrary sorting 【发布时间】:2011-11-25 15:11:40 【问题描述】:我无法理解如何使用 NSSortDescriptor 进行任意排序。
我想做这样的事情:
NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"@", @"#", @"!", @"&", @"r", @"a", nil];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES
comparator:
^(id obj1, id obj2)
NSComparisonResult comparisonResult;
//Some code that uses sortAlgorithm.
return comparisonResult;
];
这将通过键 name
对对象进行排序,以便任何以 @
开头的键,例如@home
,将出现在任何以 r
开头的键之前,例如radical
,这又会出现在任何以 a
开头的键之前,例如anything
.
以上只是一个例子。重点是启用完全任意的排序。
这将用于 NSFetchedResultsController。
//一些使用 sortAlgorithm 的代码的代码是什么样的?
编辑:
围绕我尝试实现 sortDescriptor 的代码,作为 pr。 occulus'
建议:
- (NSFetchedResultsController *)fetchedResultsController
if (__fetchedResultsController)
return __fetchedResultsController;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:self.temporaryManagedObjectContext];
//NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO comparator:^(id obj1, id obj2)
NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"#", @"!", @"@", @".", nil];
NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1];
NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1];
int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar];
int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar];
if ( idx1 < idx2 )
return NSOrderedAscending;
else if ( idx1 > idx2 )
return NSOrderedDescending;
else
return NSOrderedSame;
];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
fetchRequest.fetchBatchSize = 20;
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.temporaryManagedObjectContext sectionNameKeyPath:nil cacheName:@"Tags"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[self.fetchedResultsController performFetch:nil];
return __fetchedResultsController;
注释掉的 sortDescriptor 有效。
在实体“Tag”的对象上肯定有一个名为name
的属性。但即使没有,这似乎也不是问题。 Xcode 似乎甚至没有编译那行代码(sortDescriptor),这听起来很荒谬。断点工作得很好,但没有在特定的代码行上中断。
【问题讨论】:
最近遇到了同样的问题。我最后买了Don的theory:***.com/questions/4789782/… 【参考方案1】:您需要将obj1
和obj2
字符串的第一个字符提取为NSStrings
,在您的任意排序数组中找到它们的索引,然后比较位置。
类似这样的:(将此代码放入您的 ^
块中)
NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1];
NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1];
int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar];
int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar];
// NOTE: we haven't dealt with the case where one of the
// chars wasn't found in the array of characters. A strategy
// for this would need to be decided.
if (idx1 == idx2)
return NSOrderedSame;
if (idx1 < idx2)
return NSOrderedAscending;
return NSOrderedDescending;
未经测试,可能需要稍作调整。注意大小写字符差异。
更新: 使用自定义排序描述符和 SQL 支持的核心数据存储似乎存在问题。请参阅this question 了解更多信息。
【讨论】:
我实现了您的建议,为了测试,我将源限制为仅包含在 sortAlgorithm 数组中找到的字符。绝对没有任何反应。甚至超出了我的预期:我在 NSSortDescriptor 的定义处设置了一个断点,它永远不会中断。如果我在指令之前或之后设置断点,它就会中断。 Xcode 很简单,而且非常不方便地跳过了我对您的解决方案进行测试的尝试……我想我会在解决这个新问题时发表这条评论,以防其他人知道这一点。 我相信我上面给出的算法是正确的。正如您所注意到的,它甚至可能没有被使用/调用。 您能否发布代码以说明您实际请求排序的方式?即您使用 NSSortDescriptor 的位置。听起来排序描述符从未被使用过。您的对象上是否肯定有一个名为“name”且类型为 NSString * 的属性? 用代码更新问题。是的,您的代码看起来不错,但似乎没有使用排序描述符。 嗨,Stian,使用核心数据和自定义排序描述符似乎存在已知错误。我已经更新了上面的答案以反映这一点,请参阅最后一点。以上是关于具有任意排序的 NSSortDescriptor的主要内容,如果未能解决你的问题,请参考以下文章