NSFetchedResultsController - 委托方法在 iPhone OS 3.0 下崩溃,但不在 3.1 下
Posted
技术标签:
【中文标题】NSFetchedResultsController - 委托方法在 iPhone OS 3.0 下崩溃,但不在 3.1 下【英文标题】:NSFetchedResultsController - Delegate methods crashing under iPhone OS 3.0, but NOT UNDER 3.1 【发布时间】:2010-04-01 00:27:41 【问题描述】:大家好,我的 NSFetchedResultsController 在 3.1 SDK 下运行良好,但是我开始遇到一些奇怪的错误,特别是在我在 3.0 下尝试的委托方法中。我已经确定这与 NSFetchedResultsControllerDelegate 方法有关。这是我设置的。
inEditingMode 的内容与我实现向表中添加另一个静态部分的方式有关。
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller
[self.tableView beginUpdates];
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
NSIndexSet *sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex];
if(self.inEditingMode)
sectionSet = [NSIndexSet indexSetWithIndex:sectionIndex + 1];
switch (type)
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
break;
default:
[self.tableView reloadData];
break;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
NSIndexPath *relativeIndexPath = indexPath;
NSIndexPath *relativeNewIndexPath = newIndexPath;
if(self.inEditingMode)
relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section + 1];
relativeNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section + 1];
switch(type)
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:relativeNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:relativeIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
default:
[self.tableView reloadData];
break;
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.tableView endUpdates];
当我将实体添加到托管对象上下文时,我收到以下错误:
Serious application error. Exception was caught during Core Data change processing: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1) with userInfo (null)
我在 objc_exception_throw 上放了一个断点,崩溃似乎发生在 controllerDidChangeContent 内部。
如果我注释掉所有 self.tableView 方法,并在 controllerDidChangeContent 中放置一个 [self.tableView reloadData],一切都会按预期工作。
有人知道为什么会这样吗?
【问题讨论】:
【参考方案1】:在 NSFetchedResultsController 的文档中,特别提到了 3.0 实现中的一个错误,该错误导致控制器报告的节数与 UITableView 预期的节数之间存在差异。这是他们提供的解决方法:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
NSUInteger count = [[<#Fetched results controller#> sections] count];
if (count == 0)
count = 1;
return count;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
NSArray *sections = [<#Fetched results controller#> sections];
NSUInteger count = 0;
if ([sections count])
id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
count = [sectionInfo numberOfObjects];
return count;
请注意,OS 3.1 不需要此解决方法,因此这可以解释为什么您没有看到错误。仅当 sectionNameKeyPath 设置为 nil 时,3.0 中才需要解决方法。如果您正在为 sectionNameKeyPath 设置一个值,那么这可能不是问题。
【讨论】:
我忘了在我最初的帖子中添加,我已经实现了这个,但问题仍然存在。 实际上经过仔细检查并再次实施此修复程序,问题消失了。上次我一定是做了什么奇怪的事。非常感谢! 很高兴听到它得到了修复。 Core Data 和 NSFetchedResultsController 错误很难诊断和修复。以上是关于NSFetchedResultsController - 委托方法在 iPhone OS 3.0 下崩溃,但不在 3.1 下的主要内容,如果未能解决你的问题,请参考以下文章