【发布时间】: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 的子类中。这实现了委托方法。
-
经过一些调试后在此处添加了一些新信息...