我的应用程序中有两个UIViewControllers(与此问题相关).
他们每个人都有一个NSFetchedResultsController,在同一个实体上有一个名为News的请求.它们都具有相同的排序描述符,并且它们使用相同的UITableViewCell子类来显示所有内容.它们也都符合NSFetchedResultsControllerDelegate并运行委托方法.
唯一的区别是第一个视图控制器,我将其称为SummaryVC,仅显示获取的第一个(最多)6个对象.而另一方面,NewsFeedVC显示了所有对象,并且还可以下载更多对象.因此,SummaryVC中的委托方法只运行[self.tableView reloadData];
首次启动应用程序时,将显示SummaryVC并触发下载前6个新闻对象(从JSON转换)并将其保存在BG线程中.
然后FRC获取保存并显示实体.
然而…
在应用程序的不同部分之间推送和弹出后,间歇性地(我讨厌这个词).我回到SummaryVC,应用程序将崩溃.
它也总是一样的崩溃.
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[_PFArray objectAtIndex:]: index (46) beyond bounds (6) with userInfo (null)
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[_PFArray objectAtIndex:]: index (46) beyond bounds (6)'
在这种情况下,已经有超过6个实体加载到Core Data中. 6让我怀疑属于SummaryVC的FRC.
我已经尝试了几件事来解决这个问题.
>在viewWillDisappear上将FRC委托设置为nil.
>在viewWillDisappear上将FRC设置为nil.
>当委托方法调用时检查VC实际上是屏幕上的VC.
>在NewsFeedVC viewWillDisappear中,它现在取消其队列中的所有下载操作.
由于FRC拾取了saveContext,似乎会出现此问题.即如果我进入NewsFeedVC并触发下载,然后在VC完成之前弹出VC,那么这似乎会触发崩溃.
现在,代码明智.崩溃永远不会出现在我自己的代码中.
我可以展示FRC设置……
- (NSFetchedResultsController *)fetchedResultsController
{
if (!_fetchedResultsController) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"News"];
NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
NSSortDescriptor *sourceSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"source" ascending:YES];
NSSortDescriptor *titleSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
fetchRequest.sortDescriptors = @[dateSortDescriptor, sourceSortDescriptor, titleSortDescriptor];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.moc sectionNameKeyPath:nil cacheName:@"AllNewsItems"];
_fetchedResultsController.delegate = self;
NSError *error = nil;
[_fetchedResultsController performFetch:&error];
if (error) {
NSLog(@"Error performing fetch: %@, %@", error, [error userInfo]);
}
}
return _fetchedResultsController;
}
我想也许我应该将FRC从一个物体传递到另一个物体.即将它注入一个属性,这样只有一个属性.这是有效的吗?
编辑
是否可以为goths获取的结果控制器使用相同的缓存名称?
EDIT2
不,如果我更改缓存名称,它仍然会崩溃.
EDIT3
好的,我每次都可以复制这个.如果我启动NewsFeedVC滚动,然后在滚动时我会弹回到SummaryVC.
最佳答案 感谢Martin R的修复.
我从FetchedResultsController的初始化中删除了cacheName,它修复了问题.
谢谢.