我正在编写 iOS 6.1 代码并学习如何使用 Core Data。
fetchedObjects 的文档说:
“结果数组反射(reflect)了 Controller 托管对象上下文中托管对象的内存状态,而不是它们在持久存储中的状态。但是,返回的数组不会随着托管对象的插入、修改或删除而更新”
最后一句话与我所看到的有关。
即,我从实体中获取数据,对获取的对象进行计数 (fetchedObjects.count),然后得到我所期望的结果。
然后我创建一个新对象并保存它,然后再次执行 fetchedObjects.count 并得到与上次相同的结果 - 没有像我预期的那样增加 1。
所以,我的问题是如何在保存上下文后更新 fetchedObjects。
我读到了有关使用 NSFetchedResultsControllerDelegate here 的信息并尝试了一些建议,即我使用委托(delegate)。
我指定自己为委托(delegate)。
frc.delegate = self;
我像这样添加了委托(delegate):
@interface DB : NSObject <NSFetchedResultsControllerDelegate>
我像这样实现了委托(delegate)回调:
- (void) controllerDidChangeContent: (NSFetchedResultsController *) controller
{
;
}
一切都成功了。但我不明白为什么。
如果我删除上面的三位委托(delegate)代码,则当我创建新对象、保存上下文然后执行 fetchedObjects.count 时,我的代码会失败。由于计数不足一而失败。
如果我添加回 NSFetchedResultsControllerDelegate 和 frc.delegate = self;位并忽略回调例程,它仍然失败。
只有当我也添加回调例程(顺便说一句,它没有任何功能)时,我的代码才会成功。
这让我有点偏执 - 就像想知道如果回调什么都不做,为什么它会起作用,以及如果这会在 99% 的时间起作用,然后万一失败一次?
因此,我创建了一个 bool 值,并将其设置在回调例程中,这样我的代码在看到 bool 值翻转之前不会执行保存后计数。但是,我认为这可能是多余的 - 甚至可能是愚蠢的。
oldCount = frc.fetchedObjects.count;
<create a new object here>
frcDelegateCalled = FALSE;
[self saveDB];
[frc.managedObjectContext processPendingChanges];
while ( frcDelegateCalled == FALSE );
newCount = frc.fetchedObjects.count;
和
- (void) controllerDidChangeContent: (NSFetchedResultsController *) controller
{
frcDelegateCalled = TRUE;
}
因此,processPendingChanges 调用显然会加快更新速度,并且我的 bool 值确保回调已被调用,表明 fetchedObjects 在我重新计数之前已被更新。
我有点困惑为什么代码仅仅因为存在回调而起作用。任何人都可以在这里阐明一些要点吗?
最佳答案
只有能够了解内部情况的人才能肯定地回答,但这是我的猜测。
NSFetchedResultsController 通过监听 NSManagedObjectContextObjectsDidChangeNotification
来工作,该消息发送的数量非常多。作为一种优化,如果获取的结果 Controller 没有委托(delegate),或者委托(delegate)未实现部分或全部方法,则它可能不会响应通知。
正如 MartinR 提到的,这实际上在文档中有所说明,您所看到的是预期的行为:
Important: A delegate must implement at least one of the change tracking delegate methods in order for change tracking to be enabled. Providing an empty implementation of controllerDidChangeContent: is sufficient.
如果您想知道提取结果何时发生变化,那么无论如何您都应该在 FRC 委托(delegate)方法中执行此操作。
关于ios - 为什么/如何controllerDidChangeContent 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18685994/