何时调用getsPermanentIDsForObjects:? [英] When to call obtainPermanentIDsForObjects:?

查看:245
本文介绍了何时调用getsPermanentIDsForObjects:?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently having an issue where creating a new object on a background child thread (whose parent is the main UI thread context) and saving causes my NSFetchedResultsController to show two new objects: one with a temporary objectID, and one with a permanent objectID. This seems to be a bug of some sort, unless I'm missing something.

所以我以为我会为我创建的任何新对象手动获取永久ID。这修复了重复行问题,但引入了新的随机错误(例如无法实现对象的错误,引用我创建的新对象)。

So I thought I would manually obtain permanent IDs for any new objects I create. This fixes the duplicate row issue, but introduces new random errors (such as "could not fulfill fault for object", refering to the new object I created). If anyone has any ideas as to why any of the previously mentioned is happening, please share.

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

I'm guessing obtainPermanentIDs is a step in the right direction. But when do I call this method? Before saving to the child context? After saving the child and before the parent? After the parent? Currently my setup is this:

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 上创建一个新对象,我打算立即保存到磁盘意味着我必须在所有三个上下文中调用save:)我应该在哪里调用 getPermanentIDs

So if I create a new object on backgroundMOC, and I intend to immediatly save to disk (which means I'll have to call save: on all three contexts), where should I be calling obtainPermanentIDs?

(或者如果任何人有一个不同的解决方案,而不是调用获取永久的ids?)这个方法介绍解决什么问题反正为什么我想调用这个方法?)

(or if anyone has a different solution other than calling obtain permanent ids? What problem was this method introduced to solve anyway? Why would I want to call this method?)

更新:
我想我想出了发生了什么(这只是一个理论),虽然不是如何解决它。 Core Data显然为对象在物理保存到磁盘时生成永久ID。所以在我的情况下,这不会发生,直到我调用saveMasterMOC。目前在backgroundMOC上创建一个新对象时,我所做的是:

Update: I think I figured out what's going on (it's only a theory though), though not how to solve it. Core Data apparently generates permanent IDs for objects when they are saved physically to disk. So in my case, this won't happen until I call save on the masterMOC. Currently what I do when creating a new object on the backgroundMOC is:


  1. 保存backgroundMOC mainMOC和我的表视图可以插入新行)

  2. 保存在mainMOC(以便我可以准备保存到磁盘)

  3. save on masterMOC(最后保存到磁盘)

这里发生的是在backgroundMOC上调用save会触发UI更新,结果控制器插入仍然只有临时ID的新对象。但是,然后调用save on masterMOC会导致所有对象被分配永久ID,这会导致另一个UI更新,为此新对象插入另一行!通过注释掉最后一个masterMOC保存,我不再看到重复的条目。我在这里做错了,还是这种错误?

What's happening here is that calling save on the backgroundMOC triggers a UI update, and causes the fetched results controller to insert a new object that still has only a temporary ID. But then calling save on masterMOC causes all objects to get assigned permanent IDs, which causes another UI update, inserting another row for this "new" object! By commenting out the last masterMOC save, I no longer see duplicate entries. Am I doing something wrong here, or is this some kind of bug?

另一个更新:我认为我几乎确认了错误。我调用保存在backgroundMOC,然后设置一个计时器调用保存在mainMOC和masterMOC 5秒后。 Immediatley保存到backgroundMOC后,一个新行插入到我的表中。 5秒钟后(保存main和master时),插入另一个新行。 (首先插入的行有一个临时ID,最新的插入有永久ID)。

Another update: I think I've pretty much confirmed the bug. I call save on the backgroundMOC and then set up a timer to call save on the mainMOC and masterMOC 5 seconds later. Immediatley upon saving to the backgroundMOC, a new row is inserted into my table. 5 seconds later (upon saving main and master), another new row is inserted. (the row inserted first has a temp id, and the newest insert has permanent id).

推荐答案

,当然在一个特别困难和沮丧的一天调试一切后,发现问题是临时ID。 :)

I had the exact same issue, of course after a particularly difficult and dispiriting day of debugging everything to find out the issue was temporary IDs. :)

我有与你完全相同的结构,我也有NSManagedObjectContext的子类来编译我期望在后台和主上下文中保存的行为 - 保存在后台上下文应该保存主上下文(和主上下文应该同步任何对象改变与外部服务,这是不相关的,但值得一提的解释为什么我有两个子类),并保存在主上下文应保存主上下文。

I have the exact same structure as you, and I also have subclasses of NSManagedObjectContext to codify the behavior I expect of saves in the background and main contexts – namely, a save in the background context should save the main context (and the main context should sync any objects that changed with the external service, which is irrelevant but worth mentioning as an explanation for why I have two subclasses), and a save in the main context should save the master context.

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

In my RFSImportContext subclass (equivalent to your backgroundMOC), I implement - save: to call [super save:], then call [self.parentContext performBlock:] (self.parentContext here is equivalent to your mainM)C, where the block calls obtainPermanentIDsForObjects: with the contents of the main context's - updatedObjects and - insertedObjects arrays, then I save the main context.

我不再像你所描述的那样将临时对象泄漏到我的NSFetchedResultsController中了。一种改进情况的方法是使用RFSMainContext子类(同样,等同于您的mainMOC)来实现 - save:以获取永久对象ID,保存自身,然后保存主上下文。这个编码的行为,我们总是希望主上下文有对象在其保存时的永久ID。

I no longer have the leaking of temporary objects into my NSFetchedResultsController as you describe. A way to improve the situation a bit would be to use the RFSMainContext subclass (again, equivalent to your mainMOC) to implement - save: to obtain permanent object IDs, save itself, then save the master context. This codifies the behavior that we always want the main context to have permanent IDs for objects in it when it is saved.

这篇关于何时调用getsPermanentIDsForObjects:?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆