获取NSFetchedResultsController,NSSortDescription和sectionNameForKeyPath以协同工作

Rog*_*Rog 7 core-data objective-c nsfetchedresultscontroller ios

我目前正在开发一个具有几个实体和关系的应用程序,如下所示:

项目 << - > 类别.

我目前正在获取Item实例并使用项目的各个部分显示它们category.name.在这种情况下,我可以使用排序描述符按名称对类别进行排序,这非常简单,工作正常(下面的相关代码):

-(NSFetchedResultsController*)fetchedResultsController {
    if (fetchedResultsController_ != nil)
        return fetchedResultsController_;
    NSManagedObjectContext *moc = [order_ managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:moc];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"category.name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];
    [sortDescriptors release];
    [sortDescriptor release];
    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                          initWithFetchRequest:fetchRequest
                                          managedObjectContext:moc
                                          sectionNameKeyPath:@"category.name"
                                          cacheName:nil];
    controller.delegate = self;
    self.fetchedResultsController = controller;
    [controller release];
    [fetchRequest release];

    NSError *error = nil;
    if (![fetchedResultsController_ performFetch:&error]) {
        // Error handling
    }
    return fetchedResultsController_;
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是我需要不是按名称排序这些类别,而是通过(NSNumber*) displayOrder属于Category实体的属性.我需要在tableview上的章节标题继续使用类别name.

如果我将sortDescriptor设置为使用category.displayOrder并保持sectionNameKeyPath为category.name,则section标题工作正常但是fetDescriptor只是被fetchedResultsController忽略,并且表部分按类别的名称排序(不确定为什么??).

我的下一个想法是覆盖displayOrdergetter方法,但是由于返回类型不同,这并没有让我太过分,而且我需要实际的displayOrder值来进行节排序.

所以现在我有一个感觉有点笨重的解决方案(下面的代码),我想知道是否有更好的方法来单独使用fetchedResultsController实现相同的事情.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
// The code below grabs a reference to first object for a given section
// and uses it to return the associated category name
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    NSArray *menuItems = [sectionInfo objects];
    if ([menuItems count] > 0)
    {
        MenuItem *menuItem = [menuItems objectAtIndex:0];
        NSString *categoryName = menuItem.category.name;
        return categoryName;
    }
    return [sectionInfo name];
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些基本的东西吗?

提前感谢您的想法.

ROG

bsh*_*ley 1

这是解决问题的完美方法,Rog。

您当然不希望/不需要子类化 NSFetchedResultsController。

@aroth,我们没有足够的信息来了解他的对象模型的详细信息,但名称肯定意味着该类别不拥有项目。项目有一个类别。他的目的是显示项目列表,这就是他获取项目的原因。