按翻译后的属性对对象排序

Sort objects by translated properties

我有一个 returns 具有英语属性的对象的提取请求。我想根据 NSLocalizedString 上的翻译(俄语)等价物对这些对象进行排序。我的代码错误地返回按英语排序的数据。我正在使用以下排序描述符:

[NSSortDescriptor sortDescriptorWithKey:@"category"
                              ascending:YES
                               selector:@selector(localizedCaseInsensitiveCompare:)]]];

我的核心数据实体名为 Good,具有 categoryname 属性。我想要一个排序描述符数组,我可以将其传递给获取控制器 (setSortDescriptors:),它将首先按翻译类别排序,然后按翻译名称排序。


如果语言环境是英文且英文单词排序没问题。但是当语言环境是俄语或乌克兰语时,这种排序不起作用。这是俄语语言环境的排序数组的输入

Кулеры
Кулеры
Память
Память
Микрофоны
Блоки питания
Блоки питания
Звуковые карты
Видеокарты
Видеокарты

这是错误的。我做错了什么?谢谢!

更新 1:我正在测试它

for (int i = 0; i < sortedArray.count; i++)
{

    NSLog(@"%@", NSLocalizedString([[sortedArray objectAtIndex: i] category], nil));
}

更新二,完整代码

- (NSFetchedResultsController *) fetchedResultsController
{
    if (_fetchedResultsController != nil)
    {
        return _fetchedResultsController;
    }
    NSManagedObjectContext *context = [self managedObjectContext];

    NSFetchRequest *goodsFetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *goodsEntity = [NSEntityDescription entityForName:@"Goods" inManagedObjectContext:context];

    [goodsFetchRequest setEntity: goodsEntity];
    NSError * error = nil;

    NSArray * goods = [_managedObjectContext executeFetchRequest: goodsFetchRequest error:&error];

    NSSortDescriptor *categoryDescriptor = [[NSSortDescriptor alloc] initWithKey: @"category" ascending: YES ];
    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey: @"name" ascending: YES selector: @selector(localizedCaseInsensitiveCompare:)];

    NSArray *sortedArray = [goods sortedArrayUsingDescriptors:
                            [NSArray arrayWithObject:
                             [NSSortDescriptor sortDescriptorWithKey: @"category"
                                                           ascending:YES
                                                            selector:@selector(localizedCaseInsensitiveCompare:)]]];




       NSLog(@"------");
        for (int i = 0; i < sortedArray.count; i++)
       {

          NSLog(@"%@", NSLocalizedString([[sortedArray objectAtIndex: i] category], nil));
       }

    NSArray *sortDescriptors = @[categoryDescriptor, nameDescriptor];

    [goodsFetchRequest setSortDescriptors: sortDescriptors];


    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: goodsFetchRequest managedObjectContext: context sectionNameKeyPath:@"category" cacheName: nil];

    _fetchedResultsController.delegate = self;


    return _fetchedResultsController;
}

使用 localizedCaseInsensitiveCompare: 只是意味着在考虑一个给定的字符串是否小于另一个时(即,“Ф”和“ф”是否等同于 "case insensitive" 目的)时将参考语言环境。它不会导致系统为您调用 NSLocalizedString 类别。

我的首选解决方案是将翻译后的属性添加到您的模型对象中:

@interface Good (Translated)
@property (nonatomic, readonly) NSString *translatedCategory;
@property (nonatomic, readonly) NSString *translatedName;
@end

@implementation Good (Translated)    
- (NSString *)translatedCategory {
    return NSLocalizedString(self.category, nil);
}

- (NSString *)translatedName {
    return NSLocalizedString(self.name, nil);
}
@end

然后您可以对这些翻译后的属性进行排序和显示。我喜欢这种方法,因为我认为它使代码非常清晰,并且意味着您可以实现缓存或任何您想要的东西,或者添加其他 属性-specific 逻辑。也就是说,有时您可能希望能够根据翻译进行排序。或者你可能有很多这样的东西并且想避免创建大量的样板文件(或花哨的方法转发技巧)。

在这种情况下,您可以将自定义排序描述符与您自己的比较规则结合使用。对于简单的 NSArray,您可以使用基于比较器的排序描述符,但 Core Data 不支持块,因此我们需要一个可以调用的特殊选择器。

我们想要的是一个比较翻译字符串的比较函数。我们可以通过向 NSString 添加一个类别来做到这一点,如下所示:

@interface NSString (MYTranslatedSorting)
- (NSComparisonResult)my_translatedCaseInsensitiveCompare:(NSString *)other;
@end

@implementation NSString (MYTranslatedSorting)

- (NSComparisonResult)my_translatedCaseInsensitiveCompare:(NSString *)other {
    NSString *translatedSelf = NSLocalizedString(self, nil);
    NSString *translatedOther = NSLocalizedString(other, nil);
    return [translatedSelf localizedCaseInsensitiveCompare:translatedOther];
}
@end

现在可以调用[englishString my_translatedCaseInsensitiveCompare:otherEnglish]和return基于翻译版本的顺序。这样,我们可以使用以下排序描述符:

NSArray *sortDescriptors =
@[
  [NSSortDescriptor sortDescriptorWithKey:@"category" ascending:YES selector:@selector(my_translatedCaseInsensitiveCompare:)],
  [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(my_translatedCaseInsensitiveCompare:)],
  ];