1

我在处理 Core Data+concurrency/nested MOCs 时遇到了一些麻烦(不确定我遇到了 =P 的问题)。

我有一个方法,我传入一个托管对象 ID(我检查了它是否是永久的),并且该方法有一个子托管对象上下文,该上下文被限制在某个队列中。我可以通过从子托管对象上下文中检索对象,[managedObjectContext objectWithID:moID]但是当我尝试访问它的任何属性时(托管对象仍然是一个错误),我得到EXC_BAD_ACCESS堆栈跟踪显示_svfk_1objc_msgSend.

我知道在没有示例代码的情况下很难找出问题所在,但我希望有人可以阐明可能的原因。谢谢。=)

编辑:我尝试使用existingObjectWithID:error:而不是objectWithID:汤姆哈灵顿建议的那样,现在它有时可以工作,但有时不能工作。我也经历了一次EXC_BAD_ACCESS崩溃mergeChangesFromContextDidSaveNotification:。我怀疑这可能是一个同步问题。如果我在一个上下文中编辑某些内容并保存,而在我的子上下文中编辑其他内容,这会导致问题吗?

编辑 2:我弄清楚了为什么 existingObjectWithID:error: 有时但并非总是有效。托管对象 ID 确实是一个临时 ID(不应该mergeChangesFromContextDidSaveNotification:将其转换为永久 ID?),所以我必须obtainPermanentIDsForObjects:error:在传递 ID 之前调用。但有时在子上下文的mergeChangesFromContextDidSaveNotification:. 这可能是什么原因?谢谢。

编辑 3:这是我的 MOC 层次结构的样子。

   Persistent Store Coordinator
                |
      Persistent Store MOC
         /            \
Main Queue MOC   Child MOC (confinement)

我从主队列调用一个方法,该方法使用子 MOC(在另一个队列中)插入和更新一些托管对象,同时,我在持久存储 MOC 中插入和更新托管对象。托管对象也可以同时更新、删除和插入到主队列 MOC 中。我将 Persistent Store Coordinator 的任何更改合并到 Main Queue MOC 和 Child MOC。

还有一些问题:保存 MOC 会自动合并事物吗?如果 MOC 有待处理的合并请求,并且您在处理该合并请求之前保存,这会导致问题吗?

编辑 4:这是我初始化子 MOC 的方式。

dispatch_sync(_searchQueue, ^{
    _searchManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];

    [_searchManagedObjectContext setParentContext:_persistentStoreManagedObjectContext];
    [_searchManagedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
});

顺便说一句,我注意到只有EXC_BAD_ACCESS当通知包含已删除的对象时,合并才会崩溃(带有 )。

4

2 回答 2

1

看来你还是太努力了。对于您的子 MOC,因为它在串行队列中,请使用NSPrivateQueueConcurrencyType并将其父 MOC 设置为您的主 MOC。

NSConfinementConcurrencyType用于旧版配置。

于 2013-03-24T04:15:39.677 回答
0

我找到了解决办法。在每次保存之前,我都会这样做[moc obtainPermanentIDsForObjects:[[moc insertedObjects] allObjects] error:&error]。现在我再也没有崩溃了。

我仍然对到底发生了什么有点模糊,但这是我的理解。当您保存新插入的对象时,只有在连接到持久存储协调器的 MOC 保存时,它们才会被分配一个永久 ID。现在,要么mergeChangesFromContextDidSaveNotification:将永久 ID 向下传播(正如我所料),要么在合并之前发生了一些其他操作,或者某处存在 Apple 错误。无论如何,事先获得永久 ID 解决了这个问题。

TL;DR 核心数据+并发是困难的。

于 2013-03-21T01:17:13.637 回答