按字母顺序排列的核心数据表

Posted

技术标签:

【中文标题】按字母顺序排列的核心数据表【英文标题】:Alphabetical Core Data Table 【发布时间】:2013-01-16 22:52:26 【问题描述】:

我正在尝试创建一个表格视图,其中包含从我的应用中的 Core Data 加载的联系人列表。

我正在使用 NSFetchedResultsController。

在启动应用程序时,我从通讯录中提取联系人并将它们添加到 Core Data。这样我就可以独立于地址簿管理联系人。在创建联系人对象时,我有一个 create 方法,其中包括以下代码:

contact = [NSEntityDescription insertNewObjectForEntityForName:@"Contact" inManagedObjectContext:context];
contact.name = name;
NSString *initial = [name substringToIndex:1];
NSString *capitalisedInitial = [initial capitalizedString];
contact.nameInitial = capitalisedInitial;

这会将联系人的第一个字母保存到联系人对象的属性中。

在我的表格视图控制器代码中,我将 NSFetchedResultsController 设置如下

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Contact"];
NSSortDescriptor *descriptor1 = [NSSortDescriptor sortDescriptorWithKey:@"nameInitial" ascending:YES];
NSSortDescriptor *descriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
request.sortDescriptors = [NSArray arrayWithObjects:descriptor1, descriptor2, nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.contactsDatabase.managedObjectContext sectionNameKeyPath:@"nameInitial" cacheName:nil];

我的问题仅在我第一次运行应用程序时出现(从设备中删除应用程序后)。当我打开应用程序后直接打开联系人页面时,它显示一个完全空白的表格,并且在任何时候都不会刷新。如果我关闭应用程序(而不是删除)并重新启动它,表就可以正常工作。

另一个奇怪的是,在上面的最后一行代码中,如果我删除 @"nameInitial" 并使用 nil 代替 sectionNameKeyPath,一切正常,没有故障。但是我真的很想拥有这些部分,因为用户期望添加的快捷方式的字母列。

我猜这与数据库未准备好或表首次加载时有关,但我认为这些获取的结果控制器应该侦听数据库的更新并在准备好时进行相应更新?

任何想法都非常感谢......

编辑:

一些进一步的信息:

第一次加载 numberOfSectionsInTableView 委托方法返回 0。这似乎是问题的原因。在随后的加载中,它会返回正确的数字。我已经记录了 fetched results 控制器,它每次都在获取完整的结果集...

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

   NSLog([NSString stringWithFormat:@"Number of Sections = %i", [[self.fetchedResultsController sections] count]]);
   return [[self.fetchedResultsController sections] count];

【问题讨论】:

您的NSFetchedResultsController 有代表吗?你实现了委托方法吗? 是的。正如我所说,我第二次打开应用程序时它工作正常,而不是第一次创建数据库时...... 第二次工作正常并不意味着委托方法工作。事实上,您描述的症状与这些方法的缺失或错误实现非常一致。 抱歉耽搁了,感谢汤姆的回复。我已经将斯坦福 CoreDataTableViewController 子类化,它主要只是将 NSFetchedResultsController 文档页面中的代码复制到 UITableViewController 的子类中。这实现了委托方法。 经过一些调试后在此处添加了一些新信息... 【参考方案1】:

你是responding to changes吗?从文档中...

直到控制器的托管对象上下文收到 processPendingChanges 消息后,更改才会反映。因此,如果您更改托管对象的属性值,以使其在获取的结果控制器的结果集中的位置发生更改,则控制器报告的其索引通常不会更改,直到当前事件周期结束(调用 processPendingChanges 时) )。

听起来在您初始导入后,您的上下文没有处理它的更改,因此没有通知您的 FRC

【讨论】:

我将斯坦福 CoreDataTableViewController 子类化,它主要只是将 NSFetchedResultsController 文档页面中的代码复制到 UITableViewController 的子类中。这管理更改。我想如果问题出在这段代码上,会有更多的大惊小怪吗?

以上是关于按字母顺序排列的核心数据表的主要内容,如果未能解决你的问题,请参考以下文章

使用LocalStorage按字母顺序排列内容列表

UITableView 使用 Realm 和 Swift 具有多个按字母顺序排列的部分,多个标签与相同的数据连接

dplyr:在 R 中按字母顺序排列列

子程序必须按字母顺序排列。真的吗?

Python绘图强制按字母顺序而不是按时间顺序排序日期

如何将 NSArray 拆分为按字母顺序排列的部分以与索引表视图一起使用