【问题标题】:NSFetchedResultsController's sections array element's name not updating correctlyNSFetchedResultsController 的sections 数组元素的名称没有正确更新
【发布时间】:2017-05-10 22:50:54
【问题描述】:

我有一个简单的 NSFetchedResultsController 用法,定义了类似这个人为的例子

let request: NSFetchRequest<StudentEntity> = StudentEntity.fetchRequest()
  request.sortDescriptors = [
    NSSortDescriptor(key: "class.name", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
  ]

fetchedResultsController = NSFetchedResultsController<StudentEntity>(
    fetchRequest: request,
    managedObjectContext: context,
    sectionNameKeyPath: "class.name",
    cacheName: nil)

这有助于表格视图显示学生实体,这些实体按他们在班级关系中设置的班级分组到各个部分。类实体具有 name 属性,因此 sectionNameKeyPath 为 class.name。

当用户对学生引用的课程进行编辑时,我尝试重新加载表中的数据,但不幸的是,我发现我正在使用的部分名称没有更新。大量调试表明类实体当然更新得很好,但由于某种原因,sections[].name 没有更新。我更新类名如下

classEntity.name = newClassName

do
{
  try context.save()
}
catch let error
{
  dbgLog("failed to save context; error=\(error)")
}

tableView.reloadData();

这会导致以下数据源方法正确运行

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
  let sectionInfo = fetchedResultsController!.sections![section]
  let sectionTitle = sectionInfo.name
  let sectionStudentEntity = sectionInfo.objects![0] as! StudentEntity
  let sectionTitleFromStudent = sectionStudentEntity.class!.name!

但是 sectionTitle 不会被更新并显示旧的类名,而 sectionTitleFromStudent 正确地显示了更新后的新类名。

我假设这是因为 sectionNameKeyPath 是一个嵌套路径,并且不知何故,尽管类实体正在更新,但 fetchedResultsController 不知何故没有检测到学生实体本身的任何变化,因此不会重新创建这些部分名称。感觉像一个错误,但幸运的是我可以通过使用正确更新的 sectionTitleFromStudent 字符串来解决它。

任何人有任何想法,或者自己遇到过同样的问题?

干杯

【问题讨论】:

  • 你试过在reloadData之前做一个performFetch吗?
  • 我没有尝试过,尝试确实解决了问题。我猜它无法检测到链接实体的依赖关系仅发生变化。谢谢,如果您愿意将其作为答案,我会接受。干杯!
  • 我遇到了同样的问题,更改了sectionInfo!.numberOfObjects(在我的部分中用作标题的一部分),NSFetchedResultsController 不会检测到并且不会正确更新 tableView 部分的标题。仍在寻找解决方案。

标签: ios swift core-data nsfetchedresultscontroller


【解决方案1】:

FetchedResultsController 将仅观察其获取基础实体的对象更改(在您的情况下为 Student 对象)。因此它不知道相关Class 对象的属性发生了变化。为了让它知道,您可以重做performFetch,这应该会触发它更新其获取的对象和部分。 (请注意,performFetch 绕过了正常的 FRC 更改跟踪,因此 FRC 委托方法不会触发,但这应该不是问题,因为无论如何您都在 tableView 上执行完整的reloadData

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    相关资源
    最近更新 更多