NSFetchedResultsController在修改托管对象时通知其委托删除更改,并且从不通知插入或更新

时间:2016-06-01 21:43:13

标签: ios swift core-data uikit nsfetchedresultscontroller

我有一个UITableViewController,它是NSFetchedResultsController的委托。我的NSFetchedResultsControllerDelegate函数按Apple's documentation中的“典型用法”设置,表视图控制器作为获取结果控制器的委托属性。

我还有一些视图控制器,它们显示在表视图的顶部,可以修改托管对象。这些修改是在相同的托管对象上下文中完成的。在我的应用程序中只构建了一个托管对象上下文,并且可以全局访问它。 (我在对象上下文构造中添加了一些print语句,以确保我不会在其他地方意外地重新构造它。)

当我修改其中一个托管对象时,会调用委托函数controller:didChangeObject,但NSFetchedResultsChangeType 总是 .Delete。当我创建一个托管对象时,委托函数根本不会触发。

但是,当我手动调用call performFetch()tableView.reloadData()时,单元格将恢复到正确的状态:删除的行返回,创建任何未插入的行。

结果是删除对象按预期工作(删除了单元格),但对对象的更新会导致其单元格被删除,而对象创建不会触发单元格插入。

我试图创建一个这种行为的简单演示,但是当我从空白应用程序重新创建情境时,我没有看到这种行为。所以我的应用程序中的某些东西导致了这种奇怪的行为,但我无法弄清楚是什么。有什么想法吗?

额外信息:

谓词和排序描述符的实际构造是在几个不同的类上完成的,但是通过print(resultsController.fetchRequest.predicate)print(resultsController.fetchRequest.sortDescriptors)打印它们会得到以下结果:

  

可选(readState ==“2”或读取状态==“1”)

     

可选([(readState,ascending,compare :),(title,ascending,compare :)))

我在我的controller:didChangeObject:方法中放了一个print语句,我可以看到这只用type.rawValue = 2调用(即.Delete),并且只有当我修改对象时才会调用当我创造它们时。

1 个答案:

答案 0 :(得分:2)

NSFetchedResultsController处理其NSPredicate的方式不一致。

如果NSFetchedResultsController是使用获取请求构造的,该请求具有谓词,该谓词在整数和字符串之间进行比较,如下所示:

let predicate = NSPredicate(format: "integerAttribute == %@", String(1))

这将导致谓词字符串为:

  

integerAttribute ==" 1"

在这种情况下,初始提取工作正常:在提取的结果控制器上调用函数performFetch()将返回integerAttribute等于1的所有对象(其中{{1}类型为integerAttribute)。

但是,Int32的通知无效。对托管对象的修改会导致委托通知NSFetchedResultsControllerDelegate更改。托管对象的创建根本不会调用委托。

为了使所有这些奇怪的东西消失,修复谓词格式字符串如下:

NSFetchedResultsChangeType.Delete