我有一个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
),并且只有当我修改对象时才会调用当我创造它们时。
答案 0 :(得分:2)
与NSFetchedResultsController
处理其NSPredicate
的方式不一致。
如果NSFetchedResultsController
是使用获取请求构造的,该请求具有谓词,该谓词在整数和字符串之间进行比较,如下所示:
let predicate = NSPredicate(format: "integerAttribute == %@", String(1))
这将导致谓词字符串为:
integerAttribute ==" 1"
在这种情况下,初始提取工作正常:在提取的结果控制器上调用函数performFetch()
将返回integerAttribute
等于1
的所有对象(其中{{1}类型为integerAttribute
)。
但是,Int32
的通知无效。对托管对象的修改会导致委托通知NSFetchedResultsControllerDelegate
更改。托管对象的创建根本不会调用委托。
为了使所有这些奇怪的东西消失,修复谓词格式字符串如下:
NSFetchedResultsChangeType.Delete