不可否认,我是新人。批评欢迎。
经过一个月的尝试各种调整后,问题仍然存在。为简单起见:有三个视图控制器,称为A,B和& C。 A有2个圆形的矩形按钮,每个按钮都有一个推送到B. B是由描述的麻烦的'NSFetchedResultsController'填写的tableview。 B有一个导航栏按钮(添加)以切换到C,它接受两个数据字段并保存新项目然后弹出视图C并显示视图B.
从View C添加新项目并返回到View B会生成正确排序的列表。但是,如果我从View B返回到View A,然后再次转到View B,则列表未正确排序。每次出现View B时,它都会创建一个新的Fetched Results Controller。返回A,返回B视图未正确排序。重复 - 同样的问题。但是返回A,等待3秒,然后转到B并且哇哇正确地排序列表。我已经尝试将缓存设置为nil,并设置为在视图消失时删除的值。
View B的每个后续新显示都将显示正确排序的列表。错误的排序顺序仅在上述顺序中发生 - 添加1项后,返回一个视图,然后重新显示由FRC提供的表视图。
欢迎提出问题和建议。提前致谢。原始问题的其余部分如下所示;
我有NSFetchedResultsController
按字母顺序填写表格视图,并使用segue到另一个视图来添加项目。当我返回主表时,排序是随机的。我可以从视图中退出到层次结构上的先前视图并重新加载视图,它仍然会被随机排序。我可以连续几次重复这个。但是,如果我等待几秒钟,并按照相同的步骤操作,视图将正确排序。从保存的文件中读取时会出现正确的排序,我理解这种情况会在“稍后”自动发生。缓存设置为nil。
我有一个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];
}