为什么NSFetchedResultsController没有正确加载节标题?

时间:2010-01-24 22:46:22

标签: iphone core-data nsfetchedresultscontroller

我正在使用NSFetchedResultsController和UITableViewController。

我在Core Data模型中创建了一个瞬态字段,用作UITableView部分的标签。该字段的名称是“sectionIndex”。在我的应用程序中,“客户端”实体有许多“作业”(1到多个) - 因此我的查询检索作业将它们(通过部分)按其关联的“客户端”名称分组。

我已经在我的代码库中将此方法实现为“作业”实体上的类别。

@implementation Job (TransientMethods)

- (NSString*)sectionIndex {
    NSLog(@"JobWrapper.Job.sectionIndex: %@", self.client.name);
    return self.client.name;
}

@end

并将字符串“sectionIndex”作为sectionNameKeyPath参数传递给NSFetchedResultsController的init方法。

如果我从模拟器中删除应用程序 - 那么第一次运行应用程序时,Jobs的首页会根据此处列出的sectionIndex方法正确检索作业的Client.name中的作业并对作业进行分组。在日志中,我可以逐字地看到这个sectionIndex方法被多次调用。

但是,应用程序的后续运行不会调用sectionIndex方法...但是,部分标签仍会显示上次运行的值。这是怎么回事?在两次运行之间是否有一些神奇的缓存?

这种行为会导致更大的问题。在查看UITableView的时候,如果我发布并分配NSFetchedResultsController的谓词略有不同,如果结果集是SAME SIZE,那么这些相同的原始部分名称会显示所有新结果!

当然,没有新的日志条目。这意味着永远不会查找列,这意味着代码永远不会调用或查找瞬态字段。好像这些字段不是错误的。

现在,如果备用查询返回不同数量的结果,则会加载节名称ARE。 IE:在这种情况下,日志显示 - 在每个按钮按钮上 - 调用'sectionIndex'方法,并在UITableView中显示相应的标签。

这很疯狂 - 如果我有2个“活动”作业和2个“非活动”作业,我使用条形按钮在相应查询之间来回切换...然后将哪个部分标签与初始查询显示相关联所有后续表格视图。

当结果集中有不同的结果数时,似乎只有FetchedResultsController调用了sectionNameKeyPath字段?实际结果是不同的 - 作业名称在实际行中正确显示 - 但同样,我不认为部分标签是错误的或者正确地询问NSFetchedResultsController的部分标签。我使用以下内容:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    int count = [[results_ sections] count];
    if (count > section) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[results_ sections] objectAtIndex:section];
        return [sectionInfo name];
    }
    return nil;
}

其中results_是我为每个查询重建的NSFetchedResultsController。

我错过了什么吗?有没有办法手动清除核心数据缓存,以便它停止如此智能,并在每个查询,肯定查找sectionNameKeyPath?

为了它的价值,我取消选中了xcdatamodel中字段的“Transient”选项,但我得到了相同的结果。

最后一个异常是,当我创建第一个作为非活动的作业(而不是默认的启动视图)时 - 如果我还创建一个活动作业...非活动部分标签粘在两者上。此外,当我关闭应用程序并重新开始...非活动部分标签仍然显示---即使在标题屏幕上,我显示的活动作业应该显示完全不同的标签。

我不得不认为这是一个核心数据问题。重新启动应用程序返回数据是没有意义的。

1 个答案:

答案 0 :(得分:4)

Marcus S. Zarra's条评论,我将 cacheName 设置为nil:

results_ = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:context_ 
            sectionNameKeyPath:@"sectionIndex" 
            cacheName:nil];