使用fetchedResultsContainer在核心数据中出现严重的应用程序错误

时间:2010-10-14 14:45:54

标签: iphone core-data nsfetchedresultscontroller

尝试添加记录时出现以下错误:

  

严重的应用程序错误。例外   在Core Data变更期间被抓获   处理。这通常是一个错误   在观察者中   NSManagedObjectContextObjectsDidChangeNotification。   userInfo索引0无效   (空)

就是这样。我将断点放入我实现的所有fetchedResultsContainer委托方法中,但没有任何中断。

我将其追踪到:

  NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"titleFirstLetter" cacheName:@"Root"];

“sectionNameKeyPath”是问题所在。 “titleFirstLetter”是一个瞬态属性,我在NSManagedObject子类中创建了一个getter。

这是吸气剂:

-(NSString *)titleFirstLetter
{
  [self willAccessValueForKey:@"titleFirstLetter"];
  NSString *aString = [[self valueForKey:@"title"] uppercaseString];

  NSString *stringToReturn = [aString substringWithRange:[aString rangeOfComposedCharacterSequenceAtIndex:0]];

  [self didAccessValueForKey:@"titleFirstLetter"];
  return stringToReturn;
}

当我将sectionNameKeyPath更改为nil时,它可以工作,但显然不是我想要的。当我已经为我的模型填写了标题时它也有效,因此titleFirstLetter不会返回nil,尽管这似乎不是问题。如果我将字符串设为任意内容,如果它为零,它仍然会崩溃。

知道这里有什么?

更新: 如果我使用sectionNameKeyPath中的标题而不是transient属性,它不会崩溃,但显然会将每个项目放在自己的部分中。所以它与瞬态属性有某种关系......

UPDATE2: 使用持久属性而不是瞬态的一些初步黑客攻击,没有其他更改,似乎工作正常,所以这看起来是一个错误。我有一个错误报告打开:#8553064

UPDATE3: 好吧,抓一点。使用持久属性没有任何区别。我现在有些结束了。

谢谢!

5 个答案:

答案 0 :(得分:12)

嗯,这可能是部分(或完全)用户错误。问题是,在我添加新项目的视图中,我将[self.tableView reloadData]放在viewWillAppear方法中。评论说没有更新表格单元格,但是防止了崩溃。

然后我继续将reloadRowsAtIndexPaths:withRowAnimation:发送到表格视图,手动重新加载需要它的几个单元格。

我很高兴终于结束了!

答案 1 :(得分:2)

获取的结果控制器的默认行为是为sectionNameKeyPath的每个首字母创建一个部分。除非每个项目以不同的字母开头,否则您不应该为每个项目获取一个部分。

如果要自定义部分名称行为,请继承NSFetchedResultsController并覆盖sectionIndexTitleForSectionName:sectionIndexTitles。有关详细信息,请参阅NSFetchedResultsController文档。

答案 2 :(得分:2)

我认为这是我的问题。我收到了相同的警告信息,但我的解决方案非常不同。

如果未正确实现所有NSFetchedResultsController委托方法,则可能会出现此错误。我总是只复制并粘贴Apple的4个方法,以了解如何实现NSFetchedResultsController。

不幸的是我错过了其中一个:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

请确认你是EM,否则你会像我一样拔出你的头发。

答案 3 :(得分:1)

我发现了另一种达到同样神秘异常的方法。我的瞬态属性 - 就像你的一样,提取第一个字母 - 没有防范0长度的字符串(@“”)。尝试获取其第一个字符会引发异常并导致此核心数据错误(而不是您期望看到的异常)。

答案 4 :(得分:0)

重要

NSFetchedResultsController * consultMessageFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[[WYCoreDataStorage shareStore] coreDataHelper] mainContext] sectionNameKeyPath:nil cacheName:nil];

如果使用缓存,则必须在更改任何获取请求,其谓词或其排序描述符之前调用deleteCacheWithName :.除非将cacheName设置为nil,否则不得为多个查询重用相同的获取结果控制器。