核心数据错误:对于特定语言(如泰语),“对象必须按分区名称排序”

Core Data error: 'Objects must be sorted by section name' for specific languages such as Thai

提问人:Joshua 提问时间:4/29/2014 最后编辑:CommunityJoshua 更新时间:8/7/2021 访问量:2768

问:

CoreData:错误:(NSFetchedResultsController) 索引 72 处提取的对象具有无序部分名称“อั”。对象必须按部分名称排序'

我正在使用以下代码按书名字段排序,并在 UITableViewController 中显示书名的第一个大写字母作为节名称。

该代码在除泰语以外的所有语言中都能完美运行。我在互联网上读到有特殊的非美国字符导致此类问题(即 Æ),但我还没有找到任何解决方案。

请参阅 gschandler 响应 索引 [i] 处的获取对象具有无序部分名称 'å

FRC代码是

 NSFetchedResultsController *aFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                managedObjectContext:managedObjectContext
                                  sectionNameKeyPath:@"titleFirstLetter"
                                           cacheName:nil];

firstLetter 的代码是:

- (NSString *)titleFirstLetter {

    // support UTF-16:
    NSString* val = [self.title substringWithRange:[self.title rangeOfComposedCharacterSequenceAtIndex:0]];

    return [val uppercaseString];
}

有什么建议吗?

iOS iPhone 核心数据 nsfetchedresultscontroller

评论

0赞 jannej 1/8/2015
我有完全相同的问题,除了泰语之外,每种语言都有效。你找到任何解决方法了吗?gschandler 的方法最好吗?
0赞 Joshua 1/9/2015
起初我使用了 gschandler 的方法,因为我认为泰语是唯一有问题的语言......但是,当我发现德语中的某些字符也导致了这个问题时,我决定必须解决这个问题。我的解决方案只是在sqlite数据库中添加一个“titleFirstLetter”字段,而不是在运行时获取此字段。这样,所有的排序工作都是由sqlite数据库完成的,不会出现冲突。当然,就数据库设计而言,这不是最干净的解决方案,但这种解决方法非常有效。
0赞 jannej 1/9/2015
啊。。。现在我记得,我在另一个使用 CoreData 并在运行时创建值的应用程序中遇到了一个类似的问题,最终导致了额外的现场解决方法。似乎是最安全的方式。谢谢!:-)
0赞 RunLoop 4/2/2021
就我而言,我是按字母顺序排序的,但一个字段有一个不可见的换行符字符,这导致为其计算了错误的 sectionIndex。希望这对某人有所帮助。

答:

6赞 BossBols 6/5/2014 #1

您必须添加一个排序描述符,该描述符对 sectionNameKeyPath 执行的相同属性进行排序。

NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"titleFirstLetter" ascending:NO];   
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sort,nil]];
[fetchRequest setFetchBatchSize:20];
2赞 Tom GODDARD 8/7/2021 #2

SwiftUI 3 的另一个示例:

    @SectionedFetchRequest(sectionIdentifier: \.categoryName,
                           sortDescriptors: [NSSortDescriptor(keyPath: \Listing.category, ascending: false)],
                           predicate: NSPredicate(format: "%K = %d", #keyPath(Listing.isPublished), true),
                           animation: .default)

.categoryName 派生自 Listing.category,作为 listing 的扩展,如下所示:

extension Listing {
    @objc var categoryName: String {
        return self.category?.name ?? ""
    }
}

但是,我收到一个错误,因为我尝试按 createdOn 对列表进行排序:[NSSortDescriptor(keyPath: \Listing.createdOn, ascending: false)]

如前所述,@BossBols节和主要项的排序描述符必须相同。因此,按类别对列表进行排序是有效的。添加第二个分段排序可实现我最初的预期行为。

    @SectionedFetchRequest(sectionIdentifier: \.categoryName,
                           sortDescriptors: [NSSortDescriptor(keyPath: \Listing.category, ascending: false),
                                             NSSortDescriptor(keyPath: \Listing.createdOn, ascending: false)],
                           predicate: NSPredicate(format: "%K = %d", #keyPath(Listing.isPublished), true),
                           animation: .default)
    var listings: SectionedFetchResults<String, Listing>