nsfetchedresultscontroller 实现令人困惑

Posted

技术标签:

【中文标题】nsfetchedresultscontroller 实现令人困惑【英文标题】:nsfetchedresultscontroller implementation confusing 【发布时间】:2013-07-26 15:40:40 【问题描述】:

我在使用 NSFetchedResultsController's 方法时遇到问题。我已经阅读了实现,但它似乎没有点击。具体来说,这些方法(来自 Apple 文档):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return [[<#Fetched results controller#> sections] count];


- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section  
    id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
    return [sectionInfo name];


- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
    return [<#Fetched results controller#> sectionIndexTitles];


- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 
    return [<#Fetched results controller#> sectionForSectionIndexTitle:title atIndex:index];

我不明白的是sectionssectionIndexTitles 属性。我在初始化NSFetchedResultsController 时从未声明过这些属性,那么 XCode 是如何知道它们的以及如何在不崩溃的情况下显示它们呢?

另外,在方法中

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
        initWithFetchRequest:fetchRequest
        managedObjectContext:context
        sectionNameKeyPath:nil
        cacheName:@"<#Cache name#>"]; 

我不明白如何设置sectionNameKeyPath。例如,如果我想创建一个包含已完成和未完成任务的待办事项列表,我如何将它们分为 2 个部分?我需要任务实体中的值吗?这个值是否必须是一个字符串/我是否必须给它一个自定义设置器?

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

1.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

这是您希望在表格中显示的部分数。部分是一组具有共同点的项目。他们可能都以相同的字母开头(例如在联系人应用程序中),他们可能是属于不同联赛的球队,他们可能是按出生国家划分的人,等等......

2.

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;

这是属于所提供部分的项目数。例如,可能有 3 人出生在法国,2 人出生在德国。所以你去你获取的结果控制器询问它在那个部分有多少对象并返回数字。

3.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;

这是该部分的标题。 “法国”、“德国”等……

如果您在获取的结果控制器中指定了“sectionKeyPath”,则 section.name 将是您给它的路径名的数据对象中的分组值。

即sectionKeyPath = countryOfBirth.name;

这将返回该部分中每个人的出生国家对象中的姓名值。

4.

5.

这些都与表格右侧边缘的索引有关。它们是可选的。我建议暂时忽略这些,直到您了解其他方法为止。

所以,以我的例子为例,你可能会做这样的事情......

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestForEntityName:@"Person"];

NSSortDescriptor *countrySD = [NSSortDescriptor sortDescriptorWithKey:@"countryOfBirth.name" ascending:YES];
NSSortDescriptor *nameSD = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];

[fetchRequest setSortDescriptors:@[countrySD, nameSD]];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
    initWithFetchRequest:fetchRequest
    managedObjectContext:context
    sectionNameKeyPath:@"countryOfBirth.name"
    cacheName:nil];

这会让你得到类似......

- Albania
    - Bob
    - Margaret
- France
    - Alice
    - John
- Zimbabwe
    - Jason
    - Zachary

【讨论】:

在您的示例中,countryOfBirth.name 是什么?如果 Person 是实体,那么 countryOfBirth 将是属性,对吗?那么 .name 是什么? CountryOfBirth 在此示例中是 Country 实体。那有一个名称属性。和。与 Person 的一对一关系。

以上是关于nsfetchedresultscontroller 实现令人困惑的主要内容,如果未能解决你的问题,请参考以下文章

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