NSFetchedResultsController 按名字或姓氏排序

Posted

技术标签:

【中文标题】NSFetchedResultsController 按名字或姓氏排序【英文标题】:NSFetchedResultsController sort by first name or last name 【发布时间】:2014-08-13 19:26:20 【问题描述】:

我基本上是在尝试实现NSSortDescriptor with first name and last name,or with either first name or last name?,但使用的是 NSFetchedResultsController。我正在从通讯录中读取记录,并希望像通讯录一样显示它们。

记录将根据姓氏的第一个字母分类。如果没有姓氏,它将按名字排序,如果没有名字,它将按公司排序。

目前我有

- (NSFetchedResultsController *)fetchedResultsController 

    if (_fetchedResultsController != nil) 
        return _fetchedResultsController;
    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // read the contact list
    NSEntityDescription *entity = [Contact MR_entityDescriptionInContext:[NSManagedObjectContext MR_defaultContext]];
    [fetchRequest setEntity:entity];

    // sort the results by last name then by first name
    NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES selector:@selector(caseInsensitiveCompare:)];
    NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES selector:@selector(caseInsensitiveCompare:)];
    [fetchRequest setSortDescriptors:@[sort1, sort2]];

    // Fetch all the contacts and group them by the firstLetter in the last name. We defined this method in the CoreData/Human/Contact.h file
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_defaultContext] sectionNameKeyPath:@"firstLetter" cacheName:nil];

    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;


先按姓再按名字排序。我将如何更改它以返回上面列出的所需结果?

【问题讨论】:

【参考方案1】:

您可以在 Contact 上创建一个具有该逻辑的实例方法:

- (NSString *)sortKey

    if(self.lastName) 
        return [self.lastName substringToIndex:1];
    

    if(self.firstName) 
        return [self.firstName substringToIndex:1];
    

    return [self.companyName substringToIndex:1];

那么只要有一个NSSortDescriptor 使用密钥sortKey

【讨论】:

这正是我在章节中为 firstLetter 所做的。但是,当我这样做时,我得到一个错误*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath firstLetter not found in entity <NSSQLEntity Contact id=1>',代码是NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] initWithKey:@"firstLetter" ascending:YES selector:@selector(caseInsensitiveCompare:)]; @Bot 尝试在架构中添加firstLetter 作为字符串属性,但只是覆盖getter。 这会停止错误,但现在它会返回没有节的所有内容,因为 firstLetter 属性为空。即使我使用与您相同的代码,但在我的 Contact.m 文件中使用“firstLetter”而不是“sortKey” 我正在使用 mogenerator 所以这可能导致覆盖没有发生 我找到了一个可能的解决方案,但它可能不是最好的。当我将记录添加到核心数据时,我正在运行 firstLetter 方法并将其存储在“firstLetter”下的核心数据中,然后基于该方法运行排序。

以上是关于NSFetchedResultsController 按名字或姓氏排序的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?