如何判断“NSManagedObject”是否已被删除?
我有一个已被删除的 NSManagedObject,并且包含该托管对象的上下文已被保存。据我所知,如果 Core Data 要求持久存储在下一次保存操作期间删除对象,则 isDeleted
返回 YES
。但是,由于保存已经发生,isDeleted
返回NO
。
有什么好方法可以判断 NSManagedObject
在保存其包含的上下文之后是否已被删除?
(如果您想知道为什么引用已删除托管对象的对象尚未意识到删除,这是因为删除和上下文保存是由后台线程启动的,该后台线程使用performSelectorOnMainThread执行删除和保存: withObject:waitUntilDone:。)
I have an NSManagedObject
that has been deleted, and the context containing that managed object has been saved. I understand that isDeleted
returns YES
if Core Data will ask the persistent store to delete the object during the next save operation. However, since the save has already happened, isDeleted
returns NO
.
What is a good way to tell whether an NSManagedObject
has been deleted after its containing context has been saved?
(In case you're wondering why the object referring to the deleted managed object isn't already aware of the deletion, it's because the deletion and context save was initiated by a background thread which performed the deletion and save using performSelectorOnMainThread:withObject:waitUntilDone:
.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
检查托管对象的上下文似乎有效:
来自 Apple 关于
managedObjectContext
的文档 ...这两件事似乎都是好事。
更新:如果您尝试测试专门使用
objectWithID:
检索的托管对象是否已被删除,请查看戴夫·加拉格尔的回答。他指出,如果您使用已删除对象的 ID 调用objectWithID:
,则返回的对象将出现错误,没有其managedObjectContext
设置为零。因此,您不能简单地检查其managementObjectContext
来测试它是否已被删除。如果可以的话,请使用existingObjectWithID:error:
。如果不是,例如,您的目标是 Mac OS 10.5 或 iOS 2.0,则需要执行其他操作来测试删除。请参阅他的回答细节。Checking the context of the managed object seems to work:
From Apple's documentation on
managedObjectContext
...Both of those seem to be good things.
UPDATE: If you're trying to test whether a managed object retrieved specifically using
objectWithID:
has been deleted, check out Dave Gallagher's answer. He points out that if you callobjectWithID:
using the ID of a deleted object, the object returned will be a fault that does not have itsmanagedObjectContext
set to nil. Consequently, you can't simply check itsmanagedObjectContext
to test whether it has been deleted. UseexistingObjectWithID:error:
if you can. If not, e.g., you're targeting Mac OS 10.5 or iOS 2.0, you'll need to do something else to test for deletion. See his answer for details.更新:基于James Huddleston在下面讨论中的想法改进的答案。
旧/不推荐的答案:
我写了一个稍微好一点的方法。
self
是您的核心数据类/控制器。正如 James Huddleston 在他的回答中提到的,检查 NSManagedObject 的
-managementObjectContext
是否返回nil
是查看缓存是否存在的“相当好的”方法。 /stale NSManagedObject 已从持久存储中删除,但它并不总是准确,正如 Apple 在其文档中所述:什么时候不会返回nil?如果您使用已删除的 NSManagedObject 的
-objectID
获取不同的 NSManagedObject,如下所示:这是打印输出:
如您所见,如果 NSManagedObject 有已从持久存储中删除。
UPDATE: An improved answer, based on James Huddleston's ideas in the discussion below.
OLD/DEPRECIATED ANSWER:
I wrote a slightly better method.
self
is your Core Data class/controller.As James Huddleston mentioned in his answer, checking to see if NSManagedObject's
-managedObjectContext
returnsnil
is a "pretty good" way of seeing if a cached/stale NSManagedObject has been deleted from the Persistent Store, but it's not always accurate as Apple states in their docs:When won't it return nil? If you acquire a different NSManagedObject using the deleted NSManagedObject's
-objectID
like so:Here's the printout:
As you can see,
-managedObjectContext
won't always return nil if an NSManagedObject has been deleted from the Persistent Store.我担心其他答案中的讨论实际上隐藏了正确答案的简单性。在几乎所有情况下,正确答案是:
该答案不适用的唯一情况是:
NSObjectInaccessibleException
,或者您可以使用object.isDeleted
)I fear the discussion in the other answers is actually hiding the simplicity of the correct answer. In pretty much all cases, the correct answer is:
The only cases this answer doesn't apply in is:
NSObjectInaccessibleException
, or you can useobject.isDeleted
)由于我最近在依赖 Core Data 进行持久性的 iOS 应用程序中实现 iCloud 的经验,我意识到最好的方法是观察框架的通知。至少,比依赖一些晦涩的方法要好,这些方法可能会或可能不会告诉您某些托管对象是否已被删除。
对于“纯”核心数据应用程序,您应该在主线程上观察 NSManagedObjectContextObjectsDidChangeNotification 。通知的用户信息字典包含插入、删除和更新的托管对象的 objectID 集。
如果您在这些集合之一中找到托管对象的 objectID,那么您可以以某种不错的方式更新您的应用程序和 UI。
就是这样...有关更多信息,请参阅 Apple 的核心数据编程指南,核心数据并发章节。有一节“使用通知跟踪其他线程中的更改”,但不要忘记检查上一节“使用线程限制支持并发”。
Due to my recent experience implementing iCloud in my iOS app that relies on Core Data for persistence, I realized that the best way is observing the framework's notifications. At least, better than relying on some obscure methods that may, or may not tell you if some managed object was deleted.
For 'pure' Core Data apps you should observe NSManagedObjectContextObjectsDidChangeNotification on the main thread. The notification's user info dictionary contains sets with the managed objects' objectIDs that were inserted, deleted and updated.
If you find your managed object's objectID in one of these sets, then you can update your application and UI in some nice way.
That's it... for more information, give a chance to Apple's Core Data Programming Guide, Concurrency with Core Data chapter. There's a section "Track Changes in Other Threads Using Notifications", but don't forget to check the previous one "Use Thread Confinement to Support Concurrency".
在 Swift 3、Xcode 7.3 中验证
您还可以简单地
PRINT
每个上下文的内存引用并检查例如:( Book 和 Member 是 2 个不同的对象)
如果上下文存在但存在,它会打印类似这样的内容不同的
Verified in Swift 3, Xcode 7.3
You can also simply
PRINT
the memory references of each context and checkeg:( Book and Member being 2 different objects)
It would print something like this if the contexts exist but are different