按翻译的属性对对象排序

时间:2015-03-30 01:18:55

标签: ios objective-c nssortdescriptor

我有一个获取请求,返回具有英语属性的对象。我想根据NSLocalizedString上使用的翻译(俄语)等价物对这些对象进行排序。我的代码错误地将数据排序,就像它是英语一样。我使用以下排序描述符:

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

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


如果语言环境是英语,英语排序单词就可以了。但当语言环境是俄语或乌克兰语时,这种排序不起作用。这是俄语语言环境的排序数组的输出

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

并且错了。我做错了什么?谢谢!

更新1:我正在通过

进行测试
for (int i = 0; i < sortedArray.count; i++)
{

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

更新2,整个代码

- (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;
}

1 个答案:

答案 0 :(得分:3)

使用localizedCaseInsensitiveCompare:只是意味着在考虑一个给定字符串是否小于另一个字符串时将查询语言环境(即“Ф”和“ф”是否等同于“不区分大小写”的目的)。它不会导致系统为您调用类别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

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

在这种情况下,您可以将自定义排序描述符与您自己的比较规则一起使用。对于简单的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]并根据翻译的版本返回订单。有了它,我们可以使用以下排序描述符:

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