变音符号对从核心数据中提取的对象进行敏感排序?

时间:2013-12-27 09:47:42

标签: ios objective-c sorting

如果我想按字母顺序对项目数组进行排序而不选择NSDiacriticInsensitiveSearch我需要NSSortDescriptor使用comparator

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"SortTitle" ascending:YES comparator:
                                        ^(id obj1, id obj2) {
                                            NSInteger options = NSCaseInsensitiveSearch
                                            | NSNumericSearch                    // Numbers are compared using numeric value
                                            //  | NSDiacriticInsensitiveSearch  // Ignores diacritics (â == á == a)
                                            | NSWidthInsensitiveSearch;        // Unicode special width is ignored

                                            return [(NSString*)obj1 compare:obj2 options:options];

但是,不允许在NSFetchRequest中使用带比较器的NSSortDescriptor。 因此,我应该在从核心数据中获取结果后对结果进行排序吗?这在性能方面是否具有计算成本?

感谢

1 个答案:

答案 0 :(得分:14)

我能想到两种方法:

  1. Therefore should I sort the results after fetching them from core data? - 这是一种做法。 Apple没有提供精确的字符串排序复杂性,但我认为更大的问题是需要首先从持久性存储中获取所有对象。如果您有大量数据,则可能会影响性能。最好对其进行分析,然后才决定性能是否可以接受。

  2. 您可以尝试使用转换为SQL的NSString方法:localizedStandardCompare:localizedCompare:localizedCaseInsensitiveCompare:。可以使用以下方法创建使用任何这些方法的排序描述符:

    sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortTitle"
                                                   ascending:YES
                                                    selector:@selector(localizedCaseInsensitiveCompare:)];
    

    如果这些方法都不按您希望的方式对数据进行排序,您也可以预先对其进行预处理,例如:当标题发生变化时,您会删除变音符号等(请参阅NSHipster - CFStringTransform处的Normalize User-Generated Content)。 更新:让我假设title属性名为title,排序标题名为sortTitle。在NSManagedObject的子类中,您可以覆盖didChangeValueForKey:,如下所示:

    - (void)didChangeValueForKey:(NSString *)key
    {
        [super didChangeValueForKey:key];
    
        if ([key isEqualToString:@"title"]) {
            NSString *cleanTitle = [self.title mutableCopy];
            CFStringTransform((__bridge CFMutableStringRef)(cleanTitle), NULL, kCFStringTransformStripCombiningMarks, NO);
            self.sortTitle = [cleanTitle copy];
        }
    }