核心数据:为什么必须调用重新加载数据才能使我的应用运行?
我整晚都在调试一个简单的应用程序。 该应用程序从Web中检索一个图像(是一个…以使我的生活更轻松),并在表格视图中显示它。 我这样做是为了学习核心数据。 在我修复它之前,错误消息显示如下:
2012-09-30 06:16:12.854缩略图[34862:707] CoreData:错误:严重的应用程序错误。 在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到exception。 无效更新:无效的节数。 更新后的表视图中包含的节数(1)必须等于更新前的表视图中包含的节数(0),加上或减去插入或删除的节数(插入0,0删除)。 with userInfo(null)
基本上它说FRC委托方法出了问题 。 一方面,节号从0变为1.另一方面,“0插入,0删除”。 那么节号如何增加? 这应该不会发生..因此错误。
我通过简单地将[self.tableView reloadData]
添加到我的FRC设置方法来修复错误。 我从这篇文章中得到了灵感,但我不太明白。 答案似乎过于复杂和具体项目。 有人可以解释为什么添加reloadData
可以修复bug吗? 答案可能很简单,我希望如此。
我的应用程序的关键组件,如果重要:
- 使用
UIManagedDocument
建立核心数据堆栈 - 创建一个帮助方法,从Flickr API下载图像
-
在NSManagedObject子类文件中,尝试从持久存储中获取图像。 如果还没有,请将其插入MOC。
- (void)setupFetchedResultsController { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"BigImage" inManagedObjectContext:self.document.managedObjectContext]; [fetchRequest setEntity:entity]; NSSortDescriptor *imageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"image" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObject: imageDescriptor]; [fetchRequest setSortDescriptors:sortDescriptors]; [fetchRequest setFetchBatchSize:20]; // Create fetch results controller self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.document.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; self.fetchedResultsController.delegate = self; NSError *error; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Error in performFetch: %@, %@", error, [error userInfo]); } // Critical!! I add this line to fix the bug! [self.tableView reloadData]; }
获取的结果控制器仅跟踪第一次提取后对托管对象内容的更改。 然后使用委托方法didChangeSection
, didChangeObject
等将这些更改传播到表视图。
但是没有自动机制将初始提取的结果发送到表视图。 这就是你必须在performFetch
之后调用reloadData
的原因。
但是,有一种情况似乎会自动发挥作用。 UITableViewController
在viewWillAppear
调用reloadData
(如果第一次加载表)。 因此,如果您在viewDidLoad
设置FRC,则会在viewWillAppear
调用reloadData
,而您不必手动调用它。