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

NSFetchedResultsController notifies its Delegate of delete changes when a managed object is modified, and never notifies for Insert or Update

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

我还有一些视图控制器显示在 table 视图之上,可以在其中修改托管对象。这些修改是在 same 托管对象上下文中完成的。我的应用程序中只构造了一个托管对象上下文,它是全局访问的。 (我在我的对象上下文构造中放置了一些 print 语句,只是为了确保我不会不小心在别处重新构造它。)

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

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

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

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


额外信息:

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

Optional(readState == "2" OR readState == "1")

Optional([(readState, ascending, compare:), (title, ascending, compare:)])

我在我的 controller:didChangeObject: 方法中放置了一条打印语句,我可以看到它仅在使用 type.rawValue = 2(即 .Delete)时被调用,并且仅当我修改对象时,而不是在我创建它们时。

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

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

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

这将导致谓词字符串为:

integerAttribute == "1"

在这种情况下,初始提取工作正常:在提取结果控制器上调用函数 performFetch() returns integerAttribute 等于 [=17= 的所有对象](其中 integerAttribute 属于 Int32 类型)。

但是,NSFetchedResultsControllerDelegate 的通知无法正常工作。托管对象的修改会导致委托收到 NSFetchedResultsChangeType.Delete 更改通知。托管对象的创建根本不调用委托。

为了消除所有这些怪异现象,请按如下方式修复谓词格式字符串:

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