诚然,我是新人。欢迎批评。
经过一个月的尝试各种调整,问题仍然存在。为简单起见:有三个视图控制器,分别称为 A、B 和 C。A 有 2 个圆形矩形按钮,每个按钮都对 B 进行推送
。B 是一个由所描述的麻烦的“NSFetchedResultsController”填充的表格视图。B 有一个导航栏按钮(添加)来连接到 C,它接受两个数据字段并保存新项目,然后弹出视图 C 并显示视图 B。
从视图 C 添加新项目并返回到视图 B 会生成正确排序的列表。但是,如果我从视图 B 返回视图 A,然后再次转到视图 B,则列表未正确排序。每次出现 View B 时,它都会创建一个新的 Fetched Results Controller。返回 A,返回 B 视图未正确排序。重复 - 同样的问题。但返回 A,等待 3 秒,然后转到 B 并 woohoo 列表排序正确。我已经尝试将缓存设置为 nil,并设置为视图消失时删除的值。
视图 B 的每个后续新显示都将显示正确排序的列表。错误的排序顺序仅发生在上述顺序中 - 添加 1 个项目后,返回一个视图,然后重新显示 FRC 提供的表视图。
欢迎提出问题和建议。提前致谢。原始问题的其余部分如下所示;
我有一个NSFetchedResultsController
按字母顺序填充表格视图,并转到另一个视图以添加项目。当我返回主表时,排序是随机的。我可以从视图退出到层次结构上的先前视图并重新加载视图,它仍然会随机排序。我可以连续重复几次。但是,如果我等待几秒钟,并按照相同的步骤操作,视图将正确排序。从保存的文件中读取时似乎发生了正确的排序,我理解这是“稍后”自动发生的。缓存设置为零。
我有一个saveContext
调用,然后reloadData
在添加项目的方法中调用表视图,试图强制数据保存然后重新加载表。我已经NSFetchedResultsControllerDelegate
设置了视图。
有什么建议么?
Fetched Results Controller 的代码如下:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Player"];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor * lastNameSort = [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor * firstNameSort = [NSSortDescriptor sortDescriptorWithKey:@"firstName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
fetchRequest.sortDescriptors = [NSArray arrayWithObjects: lastNameSort, firstNameSort, nil];
NSFetchedResultsController * frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
frc.delegate = self;
NSError *error = nil;
if (![frc performFetch:&error]) {
// Handle the error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
_fetchedResultsController = frc;
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:
(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Player * player = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = player.fullName;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:
(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:
(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}