objective-c - 让 NSFetchedResultsController、NSSortDescription 和 sectionNameForKeyPath 协同工作

标签 objective-c ios core-data nsfetchedresultscontroller

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

项目 <<--> 类别

我目前正在获取 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_;
}

我现在的问题是,我需要对这些类别进行排序,而不是按名称,而是按作为 Category 实体一部分的 (NSNumber*) displayOrder 属性。 但是 我需要 tableview 上的部分标题才能继续使用类别的 name

如果我将 sortDescriptor 设置为使用 category.displayOrder 并将 sectionNameKeyPath 保留为 category.name,部分标题可以正常工作,但 sortDescriptor 会被 fetchedResultsController 忽略表格部分按类别名称排序(不确定为什么??)。

我的下一个想法是覆盖 displayOrder getter 方法,但这并没有让我走得太远,因为返回类型不同,而且我需要实际的 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];
}

我是否遗漏了一些基本的东西?

提前感谢您的想法。

罗格

最佳答案

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

你当然不想/不需要子类化 NSFetchedResultsController。

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

关于objective-c - 让 NSFetchedResultsController、NSSortDescription 和 sectionNameForKeyPath 协同工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5367419/

相关文章:

swift - 如何在不知道应该获取的实体的情况下声明数据类型 NSFetchRequest 的 let 常量

cocoa - 匹配核心数据存储中的近似字符串

objective-c - 你认为什么叫做 "helper method"?

ios - 将 Gif 图像转换为 NSData

iphone - 如何在 iPhone 应用程序中创建多个包?

ios - 托管对象与业务对象

iOS HTTPS SSL 证书

cocoa - 核心数据迁移错误消息 "' 模型不包含配置 'XYZ' .'"

ios - 无法调用委托(delegate)方法

ios - 如何在 UITableView 编辑模式下更改左侧图标