如何观察 NSManagedObject 是不是从 managedObjectContext 中移除

Posted

技术标签:

【中文标题】如何观察 NSManagedObject 是不是从 managedObjectContext 中移除【英文标题】:How to observe if a NSManagedObject is removed from managedObjectContext如何观察 NSManagedObject 是否从 managedObjectContext 中移除 【发布时间】:2013-08-24 23:03:02 【问题描述】:

我在我的应用程序中的某个时间点从持久存储协调器中删除持久存储(并加载另一个存储)和reset我的 managedObjectContext。 当我这样做时,根据文档,我还需要删除对已获取的 managedObjects 的所有引用:

所有接收者的管理对象都被“遗忘”了。如果你使用这个 方法,你应该 确保您还丢弃对使用接收器获取的任何托管对象的引用, 因为之后它们将无效。

我希望避免遍历我所有的 fetchedResultsController、缓存、可能包含 managedObjects 的数组、也存储对象的详细视图等。

相反,我更愿意观察托管对象的isInserted 状态是否发生变化。像

[myObject addObserver:self
           forKeyPath:@"isInserted"
              options:0
              context:nil];

不幸的是,这似乎不起作用。

那么 – 我如何观察 NSManagedObject 是否从 managedObjectContext 中移除?

【问题讨论】:

如果有这样的通知,你会怎么做?您仍然必须检查所有获取的结果控制器等,然后将它们清除。重置托管对象上下文会对您的数据模型造成重大冲击,并且涉及模型的所有内容都需要以某种方式做出响应。 好吧,我会在每个拥有托管对象的控制器上收到此通知。所以我不必手动遍历控制器层次结构,而是每个控制器都可以独立做出反应。这似乎更可靠。 【参考方案1】:

使用NSNotificationCenter 观察NSManagedObjectContextObjectsDidChangeNotification 消息,然后检查NSManagedObjectContextdeletedObjects 方法。详情见文档:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html#//apple_ref/occ/instm/NSManagedObjectContext/deletedObjects

【讨论】:

deletedObjects 实际上是零。然而,通知包含键 NSInvalidatedAllObjectsKey,这是有道理的,因为对象尚未被删除但已失效。【参考方案2】:

我发现观察NSPersistentStoreCoordinatorStoresDidChangeNotification 在我的情况下效果很好。 它被调用了两次——第一次是删除旧的持久存储,第二次是添加新的存储。

我仍在测试这个解决方案是否比 Nicholas 建议的方案更适合我的案例。

【讨论】:

【参考方案3】:

没有您可以观察到的内置通知或更改确实可以满足您的需求。但是很容易建立自己的。当您完成删除持久存储和重置上下文的过程时,发布您自己的通知 - @"MyAppCoreDataExploded" 或其他内容。在任何使用托管对象的控制器中观察此通知。当您收到该通知时,请清理所有本地引用。

【讨论】:

以上是关于如何观察 NSManagedObject 是不是从 managedObjectContext 中移除的主要内容,如果未能解决你的问题,请参考以下文章

-[NSManagedObject willTurnIntoFault] 是不是禁用 KVO 通知?

Swift:CoreData NSManagedObject 的自定义设置器

KVO:如何告诉观察者,那个自我改变了?

如何在 swift 中将子类 NSManagedObject 分配给 var(而不是常量)

c_cpp 简单的NSManagedObject更新观察器

从托管对象上下文中删除后使用保留的 NSManagedObject 是不是安全?