【问题标题】:How to get Core Data object from specific Object ID?如何从特定的对象 ID 获取核心数据对象?
【发布时间】:2011-06-29 10:26:39
【问题描述】:

我可以使用以下代码在 Core Data 中轻松获取对象的 ID:

NSManagedObjectID *moID = [managedObject objectID];

但是,有没有办法通过给它一个特定的对象 ID 来从核心数据存储中取出一个对象?我知道我可以通过使用 NSFetchRequest 来做到这一点,如下所示:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];

但是,我想以一种不会启动其自己的获取请求的方式来执行此操作。有什么想法吗?

【问题讨论】:

  • 但是通过获取请求方式,您可以设置要预取的属性或关系,这将为您提供出色的效率,而不是在访问时进行更多查询。

标签: ios macos cocoa core-data nsfetchrequest


【解决方案1】:

你想要:

-(NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID
                                   error:(NSError **)error

从具有该 ID 的存储中获取对象,如果不存在,则为 nil。

(请注意:NSManagedObjectContext 上有两个名称相似的方法让我大吃一惊。为了帮助他们保持直截了当,以下是其他两个方法:

-(NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID

...将使用提供的 objectID 创建一个故障对象,无论这样的对象是否实际存在于商店中。如果它不存在,任何触发错误的东西都会失败,除非你先用 NSManagedObjectContext 的insertObject: 插入对象。我发现这样做的唯一用途是将对象从一个存储复制到另一个存储,同时保留 ObjectID。

-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID

...将返回具有该 ID 的对象,如果它已被此 managedObjectContext 从存储中获取。如果有人知道这个方法有什么用,请评论。)

[eta.: 第一种方法与其他两种方法的另一个重要区别是existingObjectWithID:error: 从不返回错误;它总是为您获取整个对象。如果你想避免这种情况(例如,使用具有大 blob 属性的昂贵的获取对象),你必须聪明地使用objectWithID:objectRegisteredForID:,它们不会引发错误;或使用正确配置的获取请求。]

【讨论】:

  • -(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID 在您只想查看一个对象是否已经存在于上下文中并且不想获取它时可能很有用。
  • 我的情况。在-tableView:didSelectRowAtIndexPath: UIAlertView 上显示是/否。在“是” - 有一些与对象有关的工作。我使用NSFetchedResultsController + 远程后台CoreData 更新。所以我不能存储对象:当屏幕上显示警报时,可以更新存储并删除对象。我存储 objectId,然后在警报委托中再次检索它。因为我使用NSFetchedResultsController - 此时所有必要的对象都已经在上下文中。此外,当上下文中没有对象时,CoreData 不应进行无用的获取尝试。
  • 很好的答案,谢谢!这些方法名称真的很棘手。很容易把所有事情都弄错了
  • 很好的答案,感谢您对 objectWithId: 的澄清 - 首先调用 insertObject 以防止在尝试触发故障时引发异常对我来说确实不明显。
  • objectRegisteredForID: 在您拥有来自另一个上下文中的操作的对象ID 列表并且您只想更新在本地上下文中可能具有陈旧数据的对象ID 列表时很有用。这样可以检查您的对象图(以及因此内存使用情况),这比遍历 -registeredObjects 并检查 objectID 以查看对象是否在您的上下文中出现故障要好。
【解决方案2】:

objectWithID: 是您正在寻找的方法,并且是推荐的方法。 objectWithID: 将有效地使用 NSManagedObjectContext 仅根据需要拉取对象的级别 - 与其他一些这样做的方法不同。 objectWithID: 将正确使用父上下文、持久存储协调器和持久存储本身中的内存信息,然后再转到后备存储。

WWDC 2012 会议“核心数据最佳实践”对此进行了深入介绍。

【讨论】:

    【解决方案3】:

    Swift 5 版本:

    https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506686-existingobject

    还有object(with:)registeredObject(for:) 方法。看你需要什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多