何时调用obtainPermanentIDsForObjects:?

我目前有一个问题,在后台子线程(其父母是主UI线程上下文)上创build一个新的对象,并保存导致我的NSFetchedResultsController显示两个新的对象:一个临时objectID和一个永久objectID 。 这似乎是某种错误,除非我失去了一些东西。

所以我想我会手动获取我创build的任何新对象的永久ID。 这修复了重复的行问题,但引入了新的随机错误(例如“无法完成对象的错误”,引用了我创build的新对象)。 如果有人有任何想法,为什么之前提到的发生,请分享。

我猜obtainPermanentIDs是在正确的方向迈出的一步。 但是,我什么时候调用这个方法呢? 在保存到子上下文之前? 保存孩子之后,在父母之前? 父母之后? 目前我的设置是这样的:

 masterMOC - private queue tied to the persistent store, so physical saves happen here ----mainMOC - main queue tied to the UI, child of masterMOC -------backgroundMOC - private queue, child of mainMOC 

所以,如果我在backgroundMOC上创build一个新的对象,我打算立即保存到磁盘(这意味着我将不得不调用save:在所有三个上下文),我应该在哪里调用obtainPermanentIDs

(或者,如果有人有一个不同的解决scheme,而不是调用获得永久ID?这个方法引入了什么问题来解决呢?为什么我要调用这个方法?)

更新:我想我知道发生了什么事情(这只是一个理论),但不是如何解决它。 核心数据显然会在物理保存到磁盘时为对象生成永久ID。 所以在我的情况下,这不会发生,直到我调用保存在masterMOC。 目前我在backgroundMOC上创build一个新对象时所做的是:

  1. 保存在backgroundMOC(所以更改被推上一层到mainMOC和我的表视图可以插入新行)
  2. 保存在mainMOC上(这样我可以准备保存到磁盘)
  3. 保存在masterMOC(最后保存到磁盘)

这里发生的情况是调用saveMOC触发一个UI更新,并导致获取的结果控制器插入一个仍然只有一个临时ID的新对象。 但是,然后调用masterMOC上的保存会导致所有对象被分配永久ID,导致另一个UI更新,为这个“新”对象插入另一行! 通过评论最后的主MOC保存,我不再看到重复的条目。 我在这里做错了什么,或者这是一种错误?

另一个更新:我想我已经确认了这个错误。 我在backgroundMOC上调用保存,然后设置一个定时器,在5秒后调用mainMOC和masterMOC上的保存。 立即保存到backgroundMOC,一个新行插入到我的表中。 5秒钟后(保存主和主)时,插入另一个新行。 (首先插入的行具有临时ID,并且最新的插入具有永久ID)。

我有完全相同的问题,当然在经历了一个特别困难和令人沮丧的日子,debugging一切,找出问题是临时ID。 🙂

我和你有完全相同的结构,我也有NSManagedObjectContext的子类来编写我期望在后台和主要上下文中保存的行为 – 也就是说,在后台上下文的保存应该保存主上下文(和主上下文应该同步任何与外部服务一起更改的对象,这是无关紧要的,但值得一提的是为什么我有两个子类),在主要上下文中保存应保存主上下文。

在我的RFSImportContext子类(相当于你的backgroundMOC)中,我实现了- save:调用[super save:] ,然后调用[self.parentContext performBlock:] (self.parentContext这里等同于你的mainM)C, obtainPermanentIDsForObjects:与主要上下文的内容- updatedObjects- insertedObjects数组,然后保存主要上下文。

我不再像我们描述的那样将临时对象泄漏到我的NSFetchedResultsController中。 一种改善情况的方法是使用RFSMainContext子类(再次,等同于mainMOC)来实现- save:获得永久对象ID,保存自己,然后保存主上下文。 这编码的行为,我们总是希望主要上下文有永久ID对象时,它被保存。