【问题标题】:Serious Application Error in Core Data with fetchedResultsContainer使用 fetchedResultsContainer 在核心数据中出现严重的应用程序错误
【发布时间】:2011-04-25 11:12:15
【问题描述】:

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

严重的应用程序错误。例外 在核心数据更改期间被捕获 加工。这通常是一个错误 在观察者内 NSManagedObjectContextObjectsDidChangeNotification。 索引 0 对 userInfo 无效 (空)

就是这样。我在我实现的所有 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,尽管这似乎不是问题。如果我使字符串为 nil 时任意设置,它仍然会崩溃。

知道这里有什么吗?

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

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

更新3: 好吧,从头开始。使用持久属性没有任何区别。我现在有点不知所措了。

谢谢!

【问题讨论】:

    标签: iphone core-data nsfetchedresultscontroller


    【解决方案1】:

    重要

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

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

    【讨论】:

      【解决方案2】:

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

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

      我很高兴这终于结束了!

      【讨论】:

      • 救了我的培根!谢谢!你在哪里添加 reloadRowsAtIndexPaths:withRowAnimation:?
      【解决方案3】:

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

      如果您没有正确实现所有 NSFetchedResultsController Delegate 方法,您可能会收到此错误。我总是从 Apple 复制粘贴 4 种方法来实现 NSFetchedResultsController。

      很遗憾,我错过了其中之一:

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

      确保你有 EM,否则你会像我一样拔掉你的头发。

      【讨论】:

      • 这是一个常见问题的非常简单的解决方案。虽然我确信所有其他答案也是正确的,但这个微妙的错误也会产生同样的错误。值得注意。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 那我在这里做错了什么? assets.zerodeviation.net/sections.png这是标题为sectionNameKeyPath。
        • 为了补充这一点,文档说 IndexTitle 默认情况下是大写的第一个字母。这是真的。但我说的是章节标题。
        • indexTitles 是章节标题。查看联系人应用程序列表名称。它使用这种精确的内置方法。我不知道你为什么会遇到这个问题。很可能您在某个地方交叉了属性。
        • 并非如此。我希望它们是一样的,但如果我这样做,它们就不是了。正如文档所说,索引标题默认首字母大写,部分标题不一定。
        猜你喜欢
        • 1970-01-01
        • 2011-09-27
        • 2014-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-25
        • 1970-01-01
        相关资源
        最近更新 更多