ios - 为什么/如何controllerDidChangeContent 工作?

标签 ios core-data delegates

我正在编写 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/

相关文章:

IOS ViewController 导航路径 - 如何以编程方式向后导航

iphone - 根据设备 iPhone 或 iPod touch 关闭功能

core-data - 在 iOS13 中使用 NSPersistentCloudKitContainer 进行 CloudKit 同步

ios - 委托(delegate)意外变更

qt - 使用 TableView 作为 ListView 委托(delegate)

javascript - 如何覆盖 addEventListener 中的函数?

javascript - react native ,断断续续的独立并行动画?

ios - 解包 Optional 值时意外发现 nil

ios - 为什么 Core Data 中没有 Integer 8 NSAttributeDescription attributeType?

ios - Swift - Coredata Migration - 根据旧属性值设置新属性值